Python:搜索最大数据

时间:2013-05-13 14:39:45

标签: python list max

有两个清单。一个是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
你能帮我一个忙吗?

3 个答案:

答案 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倍