【问题标题】:Grouping together items that appear together in separate list将一起出现在单独列表中的项目组合在一起
【发布时间】:2021-04-23 17:12:13
【问题描述】:

我有 2 个嵌套列表,我想编写一些代码来运行两个列表中的每个子列表,并将两个列表中一起出现的任何元素组合在一起。我正在做的项目实际上有巨大的嵌套列表,所以我创建了以下 2 个列表来稍微简化问题(我只有一年的 python 经验)。如果可以创建一个将这两个列表中的元素组合在一起的函数,那么我可以将该函数应用于实际项目。这个问题可能类似于:Find items that appear together on multiple lists, 但我无法理解该问题中编写的代码,正如我所说,我对 python 比较陌生。

my_list = [['a', 'd', 'l'], ['c', 'e', 't'], ['q', 'x'], ['p', 'f', 'd', 'k']

sec_list = [['f', 'd', 'w', 'a'], ['c', 'e', 'u', 'h'], ['q', 'x', 'd', 'z'], ['p', 'k']]

##The output should be something like:

[['a', 'd'], ['c', 'e'], ['q', 'x'], ['p', 'k'], ['f', 'd']]```

Thanks

【问题讨论】:

  • 可能是错字 - 最后一个 ['f', 'd'] 应该在输出中吗?
  • 是的,因为 'f' 和 'd' 一起出现在 my_list 的第 4 个子列表和 sec_l​​ist 的第 1 个子列表中。抱歉,如果我没有说清楚,我希望代码检查所有子列表以查看是否有任何项目一起出现
  • 那么不应该是输出:[['d', 'a'], ['d'], ['e', 'c'], ['x', 'q'], ['d', 'f'], ['d'], ['k', 'p']] 吗?注意['d']
  • 啊,是的,尽管我打算稍后删除它,因为我想找到一起出现在 2 个不同列表中的值组,而不是单个值。但是是的,目前,['d'] 是一个有效的输出。

标签: python list grouping


【解决方案1】:

您可以使用zip 遍历两个序列并找到具有集合交集的共同元素。请注意,您的代码在 my_list

中缺少结束符 ]
my_list = [['a', 'd', 'l'], ['c', 'e', 't'], ['q', 'x'], ['p', 'f', 'd', 'k']]
sec_list = [['f', 'd', 'w', 'a'], ['c', 'e', 'u', 'h'], ['q', 'x', 'd', 'z'], ['p', 'k']]

# each item of my_list and sec_list are lists
# zip allows parallel iteration so l1 and l2 are the pairs of inner lists
# sets are designed for tasks like finding common elements
# the & sign is python for set intersection 
matches = []
for l1, l2 in zip(my_list, sec_list):
    matches.append(list(set(l1) & set(l2)))

这可以合并为一个列表理解

my_list = [['a', 'd', 'l'], ['c', 'e', 't'], ['q', 'x'], ['p', 'f', 'd', 'k']]
sec_list = [['f', 'd', 'w', 'a'], ['c', 'e', 'u', 'h'], ['q', 'x', 'd', 'z'], ['p', 'k']]
matches = [list(set(l1) & set(l2)) for l1, l2 in zip(my_list, sec_list)]

【讨论】:

  • 谢谢,我不知道 zip 命令,它在这里被证明非常有用。你可以使用 zip 同时迭代 3 个序列吗?
  • 小问题,我的错在问题中没有说清楚,但代码也应该输出[['f'], ['d'] ,因为'f'和'd'一起出现在my_list的第4个子列表和第一个sec_l​​ist 的子列表。
【解决方案2】:

基于 cmets:

my_list = [["a", "d", "l"], ["c", "e", "t"], ["q", "x"], ["p", "f", "d", "k"]]
sec_list = [
    ["f", "d", "w", "a"],
    ["c", "e", "u", "h"],
    ["q", "x", "d", "z"],
    ["p", "k"],
]

# to speed up, convert the sublists to sets
tmp1 = [set(i) for i in my_list]
tmp2 = [set(i) for i in sec_list]

out = []
for s1 in tmp1:
    for s2 in tmp2:
        m = s1 & s2
        if m:
            out.append(list(m))
print(out)

打印:

[['d', 'a'], ['d'], ['e', 'c'], ['x', 'q'], ['d', 'f'], ['d'], ['k', 'p']]

【讨论】:

    【解决方案3】:

    如果你想保留重复,你可以使用collections.Counter这个解决方案:

    from collections import Counter
    
    my_list = [['a', 'd', 'l'], ['c', 'e', 't'], ['q', 'x'], ['p', 'f', 'd', 'k', 'k']]
    
    sec_list = [['f', 'd', 'w', 'a'], ['c', 'e', 'u', 'h'], ['q', 'x', 'd', 'z'], ['p', 'k', 'k']]
    
        
    result = [list((Counter(a) & Counter(b)).elements()) for a in my_list for b in sec_list]
    result = [x for x in result if len(x) > 0]
        
    print(result)
    

    输出:

    [['a', 'd'], ['d'], ['c', 'e'], ['x', 'q'], ['f', 'd'], ['d'], ['k', 'k', 'p']]                                                                                                                                                                                                         
    

    基于 cmets 更新。

    【讨论】:

    • 与上面的答案类似,它工作得很好,但没有给出所有的值。例如,代码不输出['f', 'd']。这是一个有效的输出,因为 'f' 和 'd' 一起出现在 my_list 的第 4 个子列表和 sec_l​​ist 的第一个子列表中。对不起,我没有在问题中说清楚
    • 抱歉,我以为是错字。我根据 cmets 更新了我的答案。
    猜你喜欢
    • 1970-01-01
    • 2023-03-10
    • 2021-07-07
    • 1970-01-01
    • 2011-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多