如何比较 Python 中的两个列表列表并找到匹配值
How can I compare two lists of lists in Python and find matching values
我正在尝试根据每个列表的索引号比较两个列表:
list1 = [
['1', ['a']],
['2', ['b', 'c', 'd']],
['3', ['e']],
['4', ['f', 'g']],
['5', ['h']]
]
list2 = [
['1', ['e']],
['2', ['f', 'c']],
['3', ['h', 'g', 'a', 'd']],
['4', ['b']],
['5', ['b']],
]
我想做的是将 list1 的每一行与 list2 中的所有行和 return 匹配值进行比较。例如,在此示例中,理想的结果将是
1(list1) - 3(list2),
2-2,
2-3,
2-4,
2-5,
3-1,
4-2,
4-3
一共8个,然后删除相似的,如:2-4和4-2,1-3和3-1。
您正在寻找 'labels' 的 set intersections of the product,其中每一对本身也是一组(顺序无关紧要,如果 2-4
和 4-2
被认为是相同的)。
使用 Python set
type 可以最有效地测试交叉路口,因此在构建这些词典时,让我们预先将它们转换为集合。
所以我们需要唯一的标签,以及一种查找每个标签的关联列表的方法。这是字典的工作,因此首先将您的列表转换为字典,然后获取它们的键的并集。然后将每个配对也变成一个集合,因此 {'2', '4'}
和 {'4', '2'}
被视为相同,将结果存储在另一个集合中。请注意,在这种情况下,2-2
变为 2
,因为集合只会存储一次 '2'
。
然后我们要做的就是测试与所选键组合关联的两个列表之间是否存在交集,如果存在则包括该组合:
from itertools import product
dict1 = {k: set(l) for k, l in list1}
dict2 = {k: set(l) for k, l in list2}
keys = dict1.keys() | dict2.keys() # all unique keys in both
found = {
frozenset((k1, k2))
for k1, k2 in product(keys, repeat=2)
if dict1.get(k1, set()) & dict2.get(k2, set())
}
演示:
>>> from itertools import product
>>> dict1 = {k: set(l) for k, l in list1}
>>> dict2 = {k: set(l) for k, l in list2}
>>> keys = dict1.keys() | dict2.keys() # all unique keys in both
>>> {
... frozenset((k1, k2))
... for k1, k2 in product(keys, repeat=2)
... if dict1.get(k1, set()) & dict2.get(k2, set())
... }
{frozenset({'3', '4'}), frozenset({'2'}), frozenset({'3', '5'}), frozenset({'2', '5'}), frozenset({'2', '3'}), frozenset({'2', '4'}), frozenset({'1', '3'})}
如果你必须有双重引用,你可以post-处理结果:
for combo in found:
try:
a, b = combo
except ValueError: # doesn't contain 2 values, assume 1
a, = b, = combo
print(f'{a}-{b}')
顺序会因当前随机哈希种子而异,因此您可能需要使用排序。我得到这个输出:
3-4
2-2
3-5
2-5
2-3
2-4
1-3
我正在尝试根据每个列表的索引号比较两个列表:
list1 = [
['1', ['a']],
['2', ['b', 'c', 'd']],
['3', ['e']],
['4', ['f', 'g']],
['5', ['h']]
]
list2 = [
['1', ['e']],
['2', ['f', 'c']],
['3', ['h', 'g', 'a', 'd']],
['4', ['b']],
['5', ['b']],
]
我想做的是将 list1 的每一行与 list2 中的所有行和 return 匹配值进行比较。例如,在此示例中,理想的结果将是
1(list1) - 3(list2),
2-2,
2-3,
2-4,
2-5,
3-1,
4-2,
4-3
一共8个,然后删除相似的,如:2-4和4-2,1-3和3-1。
您正在寻找 'labels' 的 set intersections of the product,其中每一对本身也是一组(顺序无关紧要,如果 2-4
和 4-2
被认为是相同的)。
使用 Python set
type 可以最有效地测试交叉路口,因此在构建这些词典时,让我们预先将它们转换为集合。
所以我们需要唯一的标签,以及一种查找每个标签的关联列表的方法。这是字典的工作,因此首先将您的列表转换为字典,然后获取它们的键的并集。然后将每个配对也变成一个集合,因此 {'2', '4'}
和 {'4', '2'}
被视为相同,将结果存储在另一个集合中。请注意,在这种情况下,2-2
变为 2
,因为集合只会存储一次 '2'
。
然后我们要做的就是测试与所选键组合关联的两个列表之间是否存在交集,如果存在则包括该组合:
from itertools import product
dict1 = {k: set(l) for k, l in list1}
dict2 = {k: set(l) for k, l in list2}
keys = dict1.keys() | dict2.keys() # all unique keys in both
found = {
frozenset((k1, k2))
for k1, k2 in product(keys, repeat=2)
if dict1.get(k1, set()) & dict2.get(k2, set())
}
演示:
>>> from itertools import product
>>> dict1 = {k: set(l) for k, l in list1}
>>> dict2 = {k: set(l) for k, l in list2}
>>> keys = dict1.keys() | dict2.keys() # all unique keys in both
>>> {
... frozenset((k1, k2))
... for k1, k2 in product(keys, repeat=2)
... if dict1.get(k1, set()) & dict2.get(k2, set())
... }
{frozenset({'3', '4'}), frozenset({'2'}), frozenset({'3', '5'}), frozenset({'2', '5'}), frozenset({'2', '3'}), frozenset({'2', '4'}), frozenset({'1', '3'})}
如果你必须有双重引用,你可以post-处理结果:
for combo in found:
try:
a, b = combo
except ValueError: # doesn't contain 2 values, assume 1
a, = b, = combo
print(f'{a}-{b}')
顺序会因当前随机哈希种子而异,因此您可能需要使用排序。我得到这个输出:
3-4
2-2
3-5
2-5
2-3
2-4
1-3