计算同步列表中项目的组合(作为字典中的元组)

edg*_*edg 0 python

我有两个清单:

l1 = ['k', 'l', 'k', 's', 'l', 't', 'k']
l2 = ['h', 't', 'h', 't', 't', 's', 's']
Run Code Online (Sandbox Code Playgroud)

我想计算第一个列表中第i个位置的项目组合的出现次数与第二个列表中的相同位置.我希望结果如下:

kh = 2,lt = 2,st = 1,ts = 1,ks = 1

我认为最好先从列表中创建一个元组:

tupleList = zip(l1,l2)
tupeleList = [('k', 'h'), ('l', 't'), ('k', 'h'), ('s', 't'), ('l', 't'), ('t', 's'), ('k', 's')]
Run Code Online (Sandbox Code Playgroud)

然后创建一个字典来计算该元组列表中的唯一元素:

myDict = {}
for item in tupleList:
    if item[1] in myDict:
        myDi [ item[1] ] += item[2]
    else
        myDi [ item[1] ] = item[2]
Run Code Online (Sandbox Code Playgroud)

但我得到这个错误:'元组索引超出范围'.问题是什么?首先制作元组可能效率不高吗?

unu*_*tbu 6

你可以使用collections.Counter:

In [7]: import collections
In [10]: count = collections.Counter(zip(l1,l2))

In [11]: count
Out[11]: Counter({('l', 't'): 2, ('k', 'h'): 2, ('s', 't'): 1, ('t', 's'): 1, ('k', 's'): 1})
Run Code Online (Sandbox Code Playgroud)

collection.Counter是的子类dict.所以,你可以一般用它,你会一个dict,加上有机会获得一些额外的方法,如elements,most_commonsubtract.


如果你想修改你发布的代码(只需要很少的更改),它看起来像:

l1 = ['k', 'l', 'k', 's', 'l', 't', 'k']
l2 = ['h', 't', 'h', 't', 't', 's', 's']
tupleList = zip(l1,l2)
myDict = {}
for item in tupleList:
    if item in myDict:
        myDict[ item ] += 1
    else:
        myDict[ item ] = 1
print(myDict)       
Run Code Online (Sandbox Code Playgroud)

但是,dicts有一个get方法,可用于进一步简化代码:

for item in tupleList:
    myDict[item] = myDict.get(item, 0) + 1
Run Code Online (Sandbox Code Playgroud)

或者,正如@JonClements在评论中指出的那样,您可以使用 collections.defaultdict:

myDict = collections.defaultdict(int)
for item in tupleList:
    myDict[item] += 1
Run Code Online (Sandbox Code Playgroud)