我有3个列表,如下所示。
mylist1 = [["present", [1,1,1]], ["trip", [1,1,1]], ["money", [1,8,6]], ["food", [6,6,6]], ["dog", [8,6,2]]]
mylist2 = [["cat", [8,8,8]], ["trip", [5,2,8]], ["present", [8,2,6]], ["parrot", [5]], ["dogs", [8]]]
mylist3 = [["dog", [8,5]], ["trip", [8]], ["present", [6]], ["tree", [6]], ["dogs", [8]]]
我想确定这三个列表共有的单词,并将它们的值合并到一个列表中。
所以,我的输出应该如下。
[["present", [[1,1,1], [8,2,6], [6]]], ["trip", [[1,1,1], [5,2,8], [8]]]]
我目前正在执行以下操作。
lists = [mylist1, mylist2, mylist3]
mywords = []
for mylist in lists:
for item in mylist:
mywords.append(item[0])
my_new_list = []
for word in mywords:
myflag = 1
myvalues = []
for mylist in lists:
mytemp = []
for item in mylist:
if word == item[0]:
mytemp = item[1]
myvalues.append(mytemp)
if len(mytemp) == 0:
myflag = 0
if myflag != 0:
my_new_list.append([word,myvalues])
但是,当我每个列表中都有大约10000个元素并且要花几个小时才能运行时,这的效率真的很低。我想知道是否在python中有更有效的方法。
很高兴在需要时提供更多详细信息。
答案 0 :(得分:3)
在defaultdict
中将common元素用作键,其中包含要合并的值的列表。
假设公共元素在一个列表中出现的次数不超过一次,即没有重复项,并且鉴于您希望它出现在每个列表中的事实,这意味着合并列表中元素的数量必须相等列表数量;每个列表一个元素。
from collections import defaultdict
d = defaultdict(list)
for L in lists:
for k, v in L:
d[k].append(v)
output = [[k, v] for k, v in d.items() if len(v) == len(lists)]
如果要验证没有重复的假设,可以使用Counter
:
from collections import Counter
from operator import itemgetter
for L in lists:
c = Counter(map(itemgetter(0), L)).values()
if any(v > 1 for v in c.values()):
print('Invalid list:', L)
答案 1 :(得分:1)
如果您知道列表的数量,则可以使用groupby
(只要一个列表中只有一个单词类别)来做类似的事情(会稍好一些):
from itertools import groupby
mylist1 = [["present", [1,1,1]], ["trip", [1,1,1]], ["money", [1,8,6]], ["food", [6,6,6]], ["dog", [8,6,2]]]
mylist2 = [["cat", [8,8,8]], ["trip", [5,2,8]], ["present", [8,2,6]], ["parrot", [5]], ["dogs", [8]]]
mylist3 = [["dog", [8,5]], ["trip", [8]], ["present", [6]], ["tree", [6]], ["dogs", [8]]]
res = []
f = lambda x: x[0]
for k, g in groupby(sorted(mylist1 + mylist2 + mylist3, key=f), key=f):
lst = list(g)
if len(lst) == 3:
res.append([k, [x[1] for x in lst]])
print(res)
# [['present', [[1, 1, 1], [8, 2, 6], [6]]],
# ['trip', [[1, 1, 1], [5, 2, 8], [8]]]]
另一种方法是将您的列表转换为字典,并使用简单的查找方法,比上面的方法性能更高:
d1 = dict(mylist1)
d2 = dict(mylist2)
d3 = dict(mylist3)
print([[k, [v, d2[k], d3[k]]] for k, v in d1.items() if k in d2 and k in d3])
# [['present', [[1, 1, 1], [8, 2, 6], [6]]],
# ['trip', [[1, 1, 1], [5, 2, 8], [8]]]]
答案 2 :(得分:1)
选中这个
from collections import defaultdict
mylist1 = [["present", [1,1,1]], ["trip", [1,1,1]], ["money", [1,8,6]], ["food", [6,6,6]], ["dog", [8,6,2]]]
mylist2 = [["cat", [8,8,8]], ["trip", [5,2,8]], ["present", [8,2,6]], ["parrot", [5]], ["dogs", [8]]]
mylist3 = [["dog", [8,5]], ["trip", [8]], ["present", [6]], ["tree", [6]], ["dogs", [8]]]
dict1 = {d[0]: d[1:] for d in mylist1}
dict2 = {d[0]: d[1:] for d in mylist2}
dict3 = {d[0]: d[1:] for d in mylist3}
#Instead of creating the dictonaries in the above fashion you can create a loop to avoid the bad styling
dd = defaultdict(list)
for d in (dict1, dict2,dict3): # Add N dict here
for key, value in d.items():
dd[key].append(value)
print(dd)
编辑1:很抱歉,您没有注意到多余的括号,并感谢@Cristian Ciupitu注意到了。
要删除多余的方括号,请用此代码替换。
dict1 = {d[0]: d[1:][0] for d in mylist1}
希望现在输出正确。