I Z*_*I Z 1 python sorting tuples list
我有一个元组列表列表.每个元组都有这种形式(string,int),例如
lst = list()
lst.append([('a',5),('c',10),('d',3),('b',1)])
lst.append([('c',14),('f',4),('b',1)])
lst.append([('d',22),('f',2)])
Run Code Online (Sandbox Code Playgroud)
将其int视为不同文本块中每个字符串的计数.
我需要做的是产生一个最常N出现的字符串列表及其累积计数.所以在上面的例子中,a出现5次,b出现两次,c出现24次等等.如果N=2,那么我将不得不生成一对并行列表['d','c']和/ [25,24]或元组列表[('d',25),('c',24)].我需要尽快完成.我的机器有很多RAM,所以内存不是问题.
我有这个实现:
import numpy as np
def getTopN(lst,N):
sOut = []
cOut = []
for l in lst:
for tpl in l:
s = tpl[0]
c = tpl[1]
try:
i = sOut.index(s)
cOut[i] += c
except:
sOut.append(s)
cOut.append(c)
sIndAsc = np.argsort(cOut).tolist()
sIndDes = sIndAsc[::-1]
cOutDes = [cOut[sir] for sir in sIndDes]
sOutDes = [sOut[sir] for sir in sIndDes]
return sOutDes[0:N],cOutDes[0:N]
Run Code Online (Sandbox Code Playgroud)
必须有一个更好的方法,但它会是什么?
import collections
c = collections.Counter()
for x in lst:
c.update(dict(x))
print(c.most_common(2))
Run Code Online (Sandbox Code Playgroud)
输出:
[('d', 25), ('c', 24)]
Run Code Online (Sandbox Code Playgroud)
该Counter基本上是增加了一些功能的字典,所以找了一个值,并增加它的当前计是真快.dict(x)只是将元组列表转换为常规字典,将字符串映射到数字,然后update方法Counter将添加这些计数(而不是仅覆盖值,如常规字典所做).
或者,使用以下方法的更手动方法defaultdict:
c = collections.defaultdict(int)
for x, y in (t for x in lst for t in x):
c[x] += y
return [(k, c[k]) for k in sorted(c, key=c.get, reverse=True)][:2]
Run Code Online (Sandbox Code Playgroud)
正如约翰在评论中指出的那样,defaultdict确实要快得多:
In [2]: %timeit with_counter()
10000 loops, best of 3: 17.3 µs per loop
In [3]: %timeit with_dict()
100000 loops, best of 3: 4.97 µs per loop
Run Code Online (Sandbox Code Playgroud)