将两个列表与字符串和子列表进行比较

时间:2017-12-27 23:41:39

标签: python python-3.x python-3.6

我陷入困境,我必须比较列表列表,其中每个子列表包含两个字符串和一个子子列表。我想将每个子列表与下一个子列表进行比较,并在第三个项目(子子列表)中记录它们的第一个字符串和匹配的标识符。它看起来有点令人困惑。这是一个例子: 我有以下列表清单:

output-list = [['1003', '1004', ['Lion', 'Leopard', 'Panda']], 
               ['1003', '1005', ['Lion', 'Panda']], 
               ['1004', '1005', ['Lion', 'Panda', 'Tiger']], 
               ['1004', '1007', ['Tiger']], 
               ['1005', '1007', ['Cheetah', 'Goat', 'Tiger']]]

每个子列表的第一项是ID,第二项是时间戳,第三项(子子列表)包含成员。我想比较成员,如果两个子列表包含相同的成员,我想将它们与ID一起存储在新列表中。

{{1}}

我的头脑没有绕过它如何制作双循环或任何其他方式。有人可以帮我吗?对不起,我无法生成尝试代码。

5 个答案:

答案 0 :(得分:1)

您可以为每个列表计算md5哈希并比较它们,就像校验和一样。

node_md5hash = hashlib.md5(bencode.bencode(node)).hexdigest() output-list_md5hash = hashlib.md5(bencode.bencode(output-list)).hexdigest() 并且它会为节点和输出列表提供md5哈希值,如果哈希值相同,则它们的值也是如此。

您需要导入hashlib库和bencode库(您可能需要pip install bencode)。

答案 1 :(得分:1)

如果匹配列表中的顺序很重要,这是最简单的方法。

>>> out  = []
>>> for ii, elem in enumerate(node[:-1]):                                                                                                            
...     for jj in range(ii + 1, len(node)):                                                                                                          
...         common = [subelem for subelem in elem[-1] if subelem in node[jj][-1]]
...         if len(common) > 0 and common != ['']:
...             out.append([elem[0], node[jj][0], common])                                                                                       
... 
>>> for elem in out:
...     print elem
... 
['1003', '1004', ['Lion', 'Leopard', 'Panda']]
['1003', '1005', ['Lion', 'Panda']]
['1004', '1005', ['Lion', 'Panda', 'Tiger']]
['1004', '1007', ['Tiger']]
['1005', '1007', ['Cheetah', 'Goat', 'Tiger']]

如果订单不重要且列表很大,请使用set intersection作为双循环中的第一行,如下所示

common = list(set(elem[-1]).intersection(set(node[jj][-1])))

答案 2 :(得分:1)

另一种方法:

mvn clean install

答案 3 :(得分:1)

看起来你正在寻找的是python

附带的itertools.combinations
di={i[0]:set(i[2]) for i in node};outputlist=[]
for i,j in itertools.combinations(di.keys(),2):
    union=list(di[i].intersection(di[j]))
    if union and not union[0]=='':#makes sure it is not an empty set and that it does not contain only empty lists
        outputlist.append([i,j,union])

您甚至可以跳过di阶段并跳转到组合

outputlist=[]
for i,j in itertools.combinations(node,2):
    union=list(set(i[2]).intersection(set(j[2])))
    if union and not union[0]=='':#makes sure it is not an empty set and that it does not contain only empty lists
        outputlist.append([i[0], j[0],union])

另外,我建议将动物留作一组,并将空列表指定为python空列表。

修改

如果坚持使用列表,最好使用

union=filter(lambda x:x in i[2],j[2])

因为类型改变有点不高效。

全部归结为

import itertools    
output_list=filter(lambda x:x[2] and not x[2][0]=='',[[i[0],j[0],filter(lambda x:x in i[2],j[2])]for i,j in itertools.combinations(node,2)])

答案 4 :(得分:1)

我认为解决问题的最佳方法是使用combinations中的itertools,将您的列表之间的交集转换为dicts模块,如下例所示:

from itertools import combinations

def compare(node, groupping=2):
    for elm1, elm2 in combinations(node, groupping):
        condition = set(elm1[-1]) & set(elm2[-1])
        if bool(condition) and condition != {''}:
            yield elm1[0], elm2[0], list(condition)

node = [['1001', '2008-01-06T02:12:13Z', ['']],
        ['1002', '2008-01-06T02:13:55Z', ['']],
        ['1003', '2008-01-06T02:13:00Z', ['Lion', 'Rhinoceros', 'Leopard', 'Panda']],
        ['1004', '2008-01-06T02:15:20Z', ['Lion', 'Leopard', 'Eagle', 'Panda', 'Tiger']],
        ['1005', '2008-01-06T02:15:48Z', ['Lion', 'Panda', 'Cheetah', 'Goat', 'Tiger']],
        ['1006', '2008-01-06T02:13:30Z', ['']],
        ['1007', '2008-01-06T02:13:38Z', ['Cheetah', 'Tiger', 'Goat']]]

final = list(compare(node))
print(final)

输出:

[['1003', '1004', ['Lion', 'Leopard', 'Panda']],
 ['1003', '1005', ['Lion', 'Panda']],
 ['1004', '1005', ['Lion', 'Tiger', 'Panda']],
 ['1004', '1007', ['Tiger']],
 ['1005', '1007', ['Goat', 'Tiger', 'Cheetah']]]