【问题标题】:Getting combinations for content of x lists in Python在 Python 中获取 x 列表内容的组合
【发布时间】:2021-10-03 13:00:54
【问题描述】:

我的头快要爆炸了。

我有 x 个列表,每个列表都有 y 长度,如下所示:

    list1 = ["text11","text12", "text13"]
    list2 = ["text21","text22", "text23"]
    list3 = ["text31","text32"]

我正在尝试获取一个列表,其中包含每个列表中内容的所有“组合”的字符串连接,并用“+”分隔它们:

    listFinal = ["text11 + text21 + text31",
                 "text11 + text21 + text32",
                 "text11 + text22 + text31",
                 "text11 + text22 + text32",
                 "text11 + text23 + text31",
                 "text11 + text23 + text32",
                 ...
                 "text13 + text23 + text32",

如果列表的长度和数量使用嵌套循环保持不变,我可以使其工作,但由于列表的数量和长度可能会有所不同,我无法为上帝的爱弄清楚如何做到这一点。

在很多事情中,我尝试过创建一个包含我的列表的列表,然后使用嵌套循环在其中尝试执行大列表长度的操作。这给了我只有“成对”的组合。

list = [list1, list2, list3]
for l in range(len(list)):
    for li in list[l]:
        for lii in list[l+1]:
            print("li",li,"lii",lii)

这对我来说很难解释,但我希望它有点道理。

关于如何使它输出具有不同大小和长度的子列表的最终列表有什么建议吗?提前谢谢你

【问题讨论】:

    标签: python string list combinations


    【解决方案1】:

    您可以使用itertools.product 并在从产品获取的元素之间添加'+',如下所示。

    试试这个:

    import itertools
    
    list1 = ["text11","text12", "text13"]
    list2 = ["text21","text22", "text23"]
    list3 = ["text31","text32"]
    list4 = ["text41","text42","text43"]
    list5 = ["text51","text52","text53"]
    
    lists = [list1] + [list2] + [list3] + [list4] + [list5]
    
    final_list = ['+'.join(pr) for pr in (itertools.product(*lists))]
    

    输出:

    >>> final_list
    
    ['text11+text21+text31+text41+text51',
     'text11+text21+text31+text41+text52',
     'text11+text21+text31+text41+text53',
     'text11+text21+text31+text42+text51',
     'text11+text21+text31+text42+text52',
     'text11+text21+text31+text42+text53',
     'text11+text21+text31+text43+text51',
     'text11+text21+text31+text43+text52',
     'text11+text21+text31+text43+text53',
     'text11+text21+text32+text41+text51',
     'text11+text21+text32+text41+text52',
     'text11+text21+text32+text41+text53',
     'text11+text21+text32+text42+text51',
     'text11+text21+text32+text42+text52',
     'text11+text21+text32+text42+text53',
     'text11+text21+text32+text43+text51',
     'text11+text21+text32+text43+text52',
      ...
     'text13+text23+text32+text42+text53',
     'text13+text23+text32+text43+text51',
     'text13+text23+text32+text43+text52',
     'text13+text23+text32+text43+text53']
    

    更多详情:

    >>> list(itertools.product(*lists))
    
    [('text11', 'text21', 'text31', 'text41', 'text51'),
     ('text11', 'text21', 'text31', 'text41', 'text52'),
     ('text11', 'text21', 'text31', 'text41', 'text53'),
     ('text11', 'text21', 'text31', 'text42', 'text51'),
     ('text11', 'text21', 'text31', 'text42', 'text52'),
     ('text11', 'text21', 'text31', 'text42', 'text53'),
     ('text11', 'text21', 'text31', 'text43', 'text51'),
     ('text11', 'text21', 'text31', 'text43', 'text52'),
     ('text11', 'text21', 'text31', 'text43', 'text53'),
     ...
    ]
    

    【讨论】:

    • 优雅的方法。只是出于好奇,这也可以与n > 3 列表一起使用吗?
    • @marcelh 为n > 3编辑了答案
    • 这是一种简单而优雅的方法,我会将其纳入我的保留曲目中。
    【解决方案2】:

    除了列表条目的排序之外,您可能还需要以下内容:

    list1 = ["text11", "text12", "text13"]
    list2 = ["text21", "text22", "text23"]
    list3 = ["text31", "text32"]
    
    my_list = [list1, list2, list3]
    
    tmp = set(my_list[0])
    for i in range(1, len(my_list)):
        tmp = [x + '+' + y for x in tmp for y in my_list[i]]
        
    print(tmp)
    

    输出:

    ['text13+text21+text31', 'text13+text21+text32', 'text13+text22+text31', 'text13+text22+text32', 'text13+text23+text31', 'text13+text23+text32', 'text12+text21+text31', 'text12+text21+text32', 'text12+text22+text31', 'text12+text22+text32', 'text12+text23+text31', 'text12+text23+text32', 'text11+text21+text31', 'text11+text21+text32', 'text11+text22+text31', 'text11+text22+text32', 'text11+text23+text31', 'text11+text23+text32']
    

    【讨论】:

    • 我完全不知道这是如何工作的,但确实如此。非常感谢!
    • 更通用的模式,可以应用于你有多个倍数的类似问题,是创建一些保存一些临时输出的中间体。然后将此温度用于相同的计算。很高兴它有帮助。祝你工作顺利。
    【解决方案3】:
    1. 将列表合并为一个列表

    2. 然后使用内置的组合功能

        from itertools import combinations
    
        # Combine all 3 lists into 1 list
        list4 = list1 + list2 + list3
        
        # Get all combinations of length 3 (since you want the items from the 3 lists)
        combos = combinations(list4,3)
    
        # Print the combinations
        for a in list(combos):
            # Since you want them separated by "+", use "+" to join each list
            print (" + ".join(a))
    

    【讨论】:

      【解决方案4】:

      你好近啊!!!!您说只有当所有列表的长度相同时才能这样做。为什么不这样做呢?也许使用形成组合后删除的“占位符”字符?我让你考虑一下。 ;-)

      仅供参考: 我刚刚暗示的方法会起作用,但它不是最有效的。如果您想找到“正确”的方法,我会查看recursion

      我注意到您将其中一个变量命名为 list。这不是一个好主意,因为list 是一个已经定义的函数。替换它的值后,您可能无法调用它,这在您的程序中可能没问题,但通常是不好的做法,可能会导致不必要的副作用。

      其他人的答案是正确的,但我建议在使用已经编写的代码之前自己编写查找组合的函数。如果您总体上使用该原则,您会学得更快。

      祝你有美好的一天!

      【讨论】:

        猜你喜欢
        • 2017-10-31
        • 2017-07-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多