Python:使用字典计算列表中的项目

Sop*_*hie 159 python

我是Python的新手,我有一个简单的问题,比如我有一个项目列表:

['apple','red','apple','red','red','pear']
Run Code Online (Sandbox Code Playgroud)

什么是将列表项添加到字典中的最简单方法,并计算项目在列表中出现的次数.

所以对于上面的列表,我希望输出为:

{'apple': 2, 'red': 3, 'pear': 1}
Run Code Online (Sandbox Code Playgroud)

Odo*_*ois 248

在2.7和3.1中有一个特殊的Counter字典用于此目的.

>>> from collections import Counter
>>> Counter(['apple','red','apple','red','red','pear'])
Counter({'red': 3, 'apple': 2, 'pear': 1})
Run Code Online (Sandbox Code Playgroud)

  • 呸; 已经在Python库中有足够的狭隘目的了. (16认同)
  • @Glenn Maynard Counter只是一个**multiset**的实现,它不是一个不常见的数据结构IMO.事实上,C++在STL中有一个名为`std :: multiset`(也就是`std :: tr1 :: unordered_multiset`)的实现,所以Guido并不是唯一认为它的重要性. (14认同)
  • @awesomo:不,它与std :: multiset无法比较.std :: multiset允许存储多个不同但相对相等的值,这使它非常有用.(例如,您可以根据温度比较位置列表,并使用多重集查找特定温度或温度范围内的所有位置,同时快速插入一组.)计数器仅计算重复次数; 不同的价值观会丢失.这没那么有用 - 它只不过是一个包裹的词典.我怀疑是在多调整一个. (6认同)
  • 此外,它并非在所有python版本中都可用.:( (3认同)
  • 计数可能是一项狭隘的任务,但却是一项经常需要的任务。 (3认同)
  • Guido有一台时间机器官方线,或者说是个笑话. (2认同)
  • @GlennMaynard你是对的,我忽略了 std::multiset 的附加(非常有用)功能。 (2认同)

mmm*_*reg 176

我喜欢:

counts = dict()
for i in items:
  counts[i] = counts.get(i, 0) + 1
Run Code Online (Sandbox Code Playgroud)

如果密钥不存在,.get允许您指定默认值.

  • 对于那些刚接触python的人.这个答案在时间复杂性方面更好. (11认同)
  • 很好的答案。+1 我有兴趣看到它的单行版本。 (3认同)
  • 此答案也不需要任何额外的导入。+1 (2认同)

ber*_*nie 55

>>> L = ['apple','red','apple','red','red','pear']
>>> from collections import defaultdict
>>> d = defaultdict(int)
>>> for i in L:
...   d[i] += 1
>>> d
defaultdict(<type 'int'>, {'pear': 1, 'apple': 2, 'red': 3})
Run Code Online (Sandbox Code Playgroud)

  • 通过 `itertools.Counter` 我认为 @Shadow 的意思是 `collections.Counter` (2认同)

Ash*_*rma 39

只需使用列表属性计数

i = ['apple','red','apple','red','red','pear']
d = {x:i.count(x) for x in i}
print d
Run Code Online (Sandbox Code Playgroud)

输出:

{'pear': 1, 'apple': 2, 'red': 3}
Run Code Online (Sandbox Code Playgroud)

  • 虽然它有效,但这似乎效率低下. (11认同)
  • 您对数组应用`count`的次数与数组项一样多.你的解决方案是"O(n ^ 2)",其中更好的平凡解决方案是"O(n)".请参阅[riviera的答案](/sf/answers/672333791/)与[mmdreg的答案](/sf/answers/460799671/)上的评论. (10认同)
  • 也许你可以做 `d = {x:i.count(x) for x in set(i)}` (5认同)
  • @XeniaIoannidou:“O(n * unique_elements)”确实有效;除非你有很多重复,否则也好不了多少。而且还是很糟糕;构建一个“set()”基本上就是将元素添加到没有计数的哈希表中。几乎与将它们添加到计数字典中并增加计数(如果已经存在)一样多的工作,而这只是为了制作集合。我所描述的添加到字典中的内容已经是直方图问题的完整解决方案,并且您无需花费任何时间扫描原始数组中的每个唯一元素即可完成此操作。 (3认同)
  • 你能详细说明一下吗? (2认同)

Ste*_*zzo 18

我一直认为,对于一项微不足道的任务,我不想进口任何东西.但我可能是错的,取决于收藏.对比更快或更快.

items = "Whats the simpliest way to add the list items to a dictionary "

stats = {}
for i in items:
    if i in stats:
        stats[i] += 1
    else:
        stats[i] = 1

# bonus
for i in sorted(stats, key=stats.get):
    print("%d×'%s'" % (stats[i], i))
Run Code Online (Sandbox Code Playgroud)

我认为这可能比使用count()更可取,因为它只会超过迭代次数,而count可以在每次迭代时搜索整个事物.我使用这种方法来解析许多兆字节的统计数据,而且总是相当快.

  • 您可以使用像这样的默认值来简化它 d[key] = d.get(key, 0) + 1 (4认同)
  • 您的答案因其简单性而值得更多赞誉。我为此苦苦挣扎了一段时间,对其他一些用户建议导入新库等的愚蠢行为感到困惑。 (2认同)

Pra*_*yot 7

考虑collections.Counter(可从python 2.7开始). https://docs.python.org/2/library/collections.html#collections.Counter


riv*_*era 6

这个怎么样:

src = [ 'one', 'two', 'three', 'two', 'three', 'three' ]
result_dict = dict( [ (i, src.count(i)) for i in set(src) ] )
Run Code Online (Sandbox Code Playgroud)

这导致了

{'one':1,'three':3,'two':2}

  • 注意这是`O(n ^ 2)`,因为对`src.count()`的`n`调用. (9认同)

Nic*_*k T 5

L = ['apple','red','apple','red','red','pear']
d = {}
[d.__setitem__(item,1+d.get(item,0)) for item in L]
print d 
Run Code Online (Sandbox Code Playgroud)

给予{'pear': 1, 'apple': 2, 'red': 3}

  • 请不要滥用列表理解来产生这样的副作用。命令式循环更加清晰,并且不会创建无用的“None”临时列表。 (2认同)