在Python中,如何在不保留大量值的情况下获得不同值的计数
我想计算不同值的数量,我最简单的解决方案是保留一个在Python中,如何在不保留大量值的情况下获得不同值的计数,python,data-structures,Python,Data Structures,我想计算不同值的数量,我最简单的解决方案是保留一个集合并更新它,直到我完成迭代,然后我得到这个集合的len作为我的答案 但是,当数据集很大时,这是不可能的。我不仅要为每次迭代计算一种不同的值,这意味着我必须保留更多的集合 我想知道有没有更好的办法?也许其他一些内置数据结构可以帮助我?谢谢 使用。有几个python库,例如。或者查看此堆栈溢出答案以创建自己的堆栈溢出。每次向Trie中添加新词时递增计数器 下面是一个简单的嵌套字典实现。它记录单词总数和每个单词的数量 END = 'end' cla
集合
并更新它,直到我完成迭代,然后我得到这个集合的len
作为我的答案
但是,当数据集很大时,这是不可能的。我不仅要为每次迭代计算一种不同的值,这意味着我必须保留更多的集合
我想知道有没有更好的办法?也许其他一些内置数据结构可以帮助我?谢谢 使用。有几个python库,例如。或者查看此堆栈溢出答案以创建自己的堆栈溢出。每次向Trie中添加新词时递增计数器
下面是一个简单的嵌套字典实现。它记录单词总数和每个单词的数量
END = 'end'
class Trie:
def __init__(self, words_iterable):
self.root = {}
self.size = 0
for word in iter(words_iterable):
self.insert(word)
def insert(self, word):
current_dict = self.root
for letter in word:
current_dict = current_dict.setdefault(letter, {})
if END not in current_dict:
current_dict[END] = 0
self.size += 1
current_dict[END] += 1
def count(self, word):
current_dict = self.root
for letter in word:
current_dict = current_dict.setdefault(letter, {})
return current_dict.get(END, 0)
def __len__(self):
return self.size
def __str__(self):
return str(self.root)
示例:
trie = Trie('one two one three four'.split())
trie.insert('four')
print(trie)
>>> {'o': {'n': {'e': {'end': 2}}}, 't': {'w': {'o': {'end': 1}}, 'h': {'r':
{'e': {'e': {'end': 1}}}}}, 'f': {'o': {'u': {'r': {'end': 2}}}}}
len(trie)
>>> 4
trie.count('four')
>>> 2
使用一个。有几个python库,例如。或者查看此堆栈溢出答案以创建自己的堆栈溢出。每次向Trie中添加新词时递增计数器
下面是一个简单的嵌套字典实现。它记录单词总数和每个单词的数量
END = 'end'
class Trie:
def __init__(self, words_iterable):
self.root = {}
self.size = 0
for word in iter(words_iterable):
self.insert(word)
def insert(self, word):
current_dict = self.root
for letter in word:
current_dict = current_dict.setdefault(letter, {})
if END not in current_dict:
current_dict[END] = 0
self.size += 1
current_dict[END] += 1
def count(self, word):
current_dict = self.root
for letter in word:
current_dict = current_dict.setdefault(letter, {})
return current_dict.get(END, 0)
def __len__(self):
return self.size
def __str__(self):
return str(self.root)
示例:
trie = Trie('one two one three four'.split())
trie.insert('four')
print(trie)
>>> {'o': {'n': {'e': {'end': 2}}}, 't': {'w': {'o': {'end': 1}}, 'h': {'r':
{'e': {'e': {'end': 1}}}}}, 'f': {'o': {'u': {'r': {'end': 2}}}}}
len(trie)
>>> 4
trie.count('four')
>>> 2
如果您对O(NlogN)时间(即首先对列表进行排序)没有问题,可以使用恒定内存执行此操作。@cs95 timsort是O(n)空间复杂度,因此它不能完全解决此问题。我们需要利用这个世界Quicksort@OlivierMelançon aaah。。。公平地说,一些快速研究表明timsort使用的内存可能高达N//2(这仍然是线性的,对OP来说是一个挑战)。@cs95抱歉,我不太理解你的解决方案。我的情况是:我必须迭代一个文档集来计算当前文档中单词的一些属性。这些属性包括distinct value count(例如,引用当前文档的distinct document的数量),因此我为这些属性维护一个
集
,并最终计算该集的长度。我怎样才能把你的解决方案应用到这个问题上?谢谢只要你的设备能存储在内存中,这可能是你最好的解决方案。大多数专门的解决方案通常处理这个数据集大于内存的问题。如果您对O(NlogN)时间(即首先对列表进行排序)没有问题,那么您可以使用恒定内存来完成这项工作。@cs95 timsort是O(n)空间复杂度,因此它不能完全解决这个问题。我们需要利用这个世界Quicksort@OlivierMelançon aaah。。。公平地说,一些快速研究表明timsort使用的内存可能高达N//2(这仍然是线性的,对OP来说是一个挑战)。@cs95抱歉,我不太理解你的解决方案。我的情况是:我必须迭代一个文档集来计算当前文档中单词的一些属性。这些属性包括distinct value count(例如,引用当前文档的distinct document的数量),因此我为这些属性维护一个集
,并最终计算该集的长度。我怎样才能把你的解决方案应用到这个问题上?谢谢只要你的设备能存储在内存中,这可能是你最好的解决方案。大多数专门的解决方案通常处理数据集大于内存的问题。由于额外的dict和字节码解释的所有开销,这很可能比直接的集合解决方案要昂贵得多。字典字典字典如何比单个集合更好?这似乎解决了不同的问题。这绝对值得一试,但取决于OP数据集。这会带来很大的开销,但由于单词之间的冲突,随着时间的推移,大小可能会越来越慢。我同意简单的python嵌套字典实现可能并不理想。如果OP需要更好的空间/时间效率,那么玛丽莎TIE链接就要实现Cython,并且有一个具有Python绑定的C++实现。在Marisa trie链接上,它表示可以比普通字典(set)节省50-100倍的空间。但它取决于数据集。@RadosławCybulski就像一个集合一样,Trie只存储每个字符串的一个副本。它可以在一个集合上节省空间,因为字符串的每个前缀只存储一次。在本例中,“two”和“three”中的“t”只存储一次。由于额外的dict和字节码解释的所有开销,这很可能比直接的集合解决方案要昂贵得多。字典字典字典如何比单个集合更好?这似乎解决了不同的问题。这绝对值得一试,但取决于OP数据集。这会带来很大的开销,但由于单词之间的冲突,随着时间的推移,大小可能会越来越慢。我同意简单的python嵌套字典实现可能并不理想。如果OP需要更好的空间/时间效率,那么玛丽莎TIE链接就要实现Cython,并且有一个具有Python绑定的C++实现。在Marisa trie链接上,它表示可以比普通字典(set)节省50-100倍的空间。但它取决于数据集。@RadosławCybulski就像一个集合一样,Trie只存储每个字符串的一个副本。它可以在一个集合上节省空间,因为字符串的每个前缀只存储一次。在本例中,“two”和“three”中的“t”只存储一次。