有两个清单。一个是code_list,另一个是点
code_list= ['ab','ca','gc','ab','we','ca']
points = [30, 20, 40, 20, 10, -10]
这两个列表相互连接如下:'ab'= 30,'ca'= 20,'gc'= 40,'ab'= 20,'we'= 10,'ca'= - 10
从这两个列表中,如果有相同的元素,我想得到每个元素的总和。最后,我会得到一个最重要的元素。 我希望能得到如下的简单结果:
'ab' has the biggest point: 50
你能帮我一个忙吗?
答案 0 :(得分:4)
您可以使用collections.Counter()
实例:
>>> from collections import Counter
>>> code_list= ['ab','ca','gc','ab','we','ca']
>>> points = [30, 20, 40, 20, 10, -10]
>>> c = Counter()
>>> for key, val in zip(code_list, points):
... c[key] += val
...
>>> c.most_common(1)
[('ab', 50)]
zip()
将您的两个输入列表配对。
最后一次调用使Counter()
在这里有用,.most_common()
调用仅在内部使用max()
一个项目,但对于大于1 heapq.nlargest()
的参数,使用,没有参数或要求len(c)
,sorted()
被使用。
答案 1 :(得分:1)
还有另一种方法,使用collections.defaultdict
:
>>> di = collections.defaultdict(int)
>>> for k,v in zip(code_list, points):
di[k] += v
>>> max(di, key=lambda x:di[x])
'ab'
如果您出于某种原因不想使用defaultdict
,请执行以下操作:
>>> di = {}
>>> for k,v in zip(code_list, points):
if k not in di:
di[k] = 0
# or as suggested by Martijn Pieters
# di[k] = di.get(k, 0) + v
di[k] += v
答案 2 :(得分:1)
另一种方式:
ans={}
for k,v in zip(code_list,points):
ans.setdefault(k,[]).append(v)
print max(ans, key=lambda k:sum(ans[k]))
这将创建code_points
中的键的映射,其中包含相关值的列表,如下所示:
{'ca': [20, -10], 'ab': [30, 20], 'gc': [40], 'we': [10]}
行max(ans, key=lambda k:sum(ans[k]))
采用该映射并将列表汇总在一起以获得最大值。
这是另一种方式:
ans={k:0 for k in set(code_list)}
for k,v in zip(code_list,points):
ans[k]+=v
print max(ans, key=lambda k: ans[k])
行ans={k:0 for k in set(code_list)}
使用code_list
中的每个唯一键创建一个字典,其值为0.然后循环将它们全部添加。
或者,正如评论中所述,这可能更好:
ans=dict.fromkeys(code_list,0)
for k,v in zip(code_list,points):
ans[k]+=v
print max(ans, key=lambda k: ans[k])
由于对性能有一些讨论,这是一个测试:
from __future__ import print_function # will run on Py 2.7 or 3.X
import timeit
from collections import Counter
from collections import defaultdict
points = [30, 20, 40, 20, 10, -10]
code_list= ['ab','ca','gc','ab','we','ca']
o1='''\
c=Counter()
for key, val in zip(code_list, points):
c[key] += val
ans=c.most_common(1)
'''
o2='''\
ans=defaultdict(int)
for k,v in zip(code_list,points):
ans[k]+=v
m=max(ans, key=lambda k:ans[k])
'''
o3='''\
ans={}
for k,v in zip(code_list,points):
ans.setdefault(k,[]).append(v)
m=max(ans, key=lambda k:sum(ans[k]))
'''
o4='''\
ans={k:0 for k in set(code_list)}
for k,v in zip(code_list,points):
ans[k]+=v
m=max(ans, key=lambda k: ans[k])
'''
o5='''\
ans=dict.fromkeys(code_list,0)
for k,v in zip(code_list,points):
ans[k]+=v
m=max(ans, key=lambda k: ans[k])
'''
o6='''\
ans={}
for k,v in zip(code_list,points):
ans[k]=ans.get(k,0)+v
m=max(ans, key=lambda k: ans[k])
'''
fmt='{:20}{:>8.4f} seconds'
print (fmt.format('Counter:',timeit.timeit(o1, setup='from __main__ import points, Counter, code_list')))
print (fmt.format('defaultdict:',timeit.timeit(o2, setup='from __main__ import points, defaultdict, code_list')))
print (fmt.format('setdefault:',timeit.timeit(o3,setup='from __main__ import points, code_list')))
print (fmt.format('dict comprehension:',timeit.timeit(o4,setup='from __main__ import points, code_list')))
print (fmt.format('fromkeys:',timeit.timeit(o5,setup='from __main__ import points, code_list')))
print (fmt.format('dict.get():',timeit.timeit(o6,setup='from __main__ import points, code_list')))
打印(在我的机器上使用Python 3.3):
Counter: 13.0980 seconds
defaultdict: 4.8093 seconds
setdefault: 5.3016 seconds
dict comprehension: 3.8282 seconds
fromkeys: 3.3764 seconds
dict.get(): 3.4785 seconds
这表明Counter()
非常慢。最快的是快3倍