【问题标题】:Get the combination of 2 lists获取 2 个列表的组合
【发布时间】:2020-08-19 15:14:11
【问题描述】:

我重新发布这个问题是因为我在上一篇文章中被告知有一个解决方案。

我有 2 个列表:

list1 = ["foo", "bar", "lorem"]
list2 = ["X", "Y"]

我想从这两个列表中获得可能的组合,意思是:

[["foo", "bar", "lorem"],
 ["foo", "bar", "loremX"],
 ["foo", "barX", "loremX"],
 ["fooX", "bar", "loremX"],
 ["fooX", "barX", "loremX"],
 ["foo", "barX", "lorem"],
 ["fooX", "barX", "lorem"],
 ["fooX", "bar", "lorem"],

 ["foo", "bar", "lorem"],
 ["foo", "bar", "loremY"],
 ["foo", "barY", "loremY"],
 ["fooY", "bar", "loremY"],
 ["fooY", "barY", "loremY"],
 ["foo", "barY", "lorem"],
 ["fooY", "barY", "lorem"],
 ["fooY", "bar", "lorem"]]

希望我没有错过任何组合。

这个有点迷失了。

它可能应该是 itertools.combinations_with_replacement 的东西

谢谢。

编辑

首先,感谢@titusarmah99 的出色回答。 我设法采用了他的第二个非常简单的解决方案并将其通用:

import itertools

list1 = ["foo", "bar", "lorem"]
list2 = ["X", "Y"]
list2new = [""] + list2
newList = [[list1[i]+list2new[j] for j in range(len(list2new))] for i in range(len(list1))]

for index in range(1, len(list2) + 1):
    for c in itertools.product([0,index],repeat=len(list1)):
        tmp = [newList[i][c[i]] for i in range(len(c))]
        print(tmp)

【问题讨论】:

  • 我认为,您显示的最终结果与所有可能组合的定义不太匹配。你能解释一下你想找到什么吗?
  • @titusarmah99 你说得对,我刚刚注意到了。我想找到 list1 中的值 + list2 中的值但不是 list2 中的值 + list1 中的值的所有组合。
  • ['fooX', 'bar', 'loremX']['fooX', 'barX', 'loremY']['fooX', 'barY', 'lorem'] 这样的组合呢?
  • @titusarmah99 如果您有没有它们的解决方案,那就太好了。否则,我将能够处理它们。

标签: python-3.x list permute


【解决方案1】:

这里的关键是使用旋转。 There are many ways to rotate an array,我将使用deque

from collections import deque

list1 = ["foo", "bar", "lorem"]
list2 = ["X", "Y"]
list2new = [""] + list2
print(list2new) # ['', 'X', 'Y']

newList = [[list1[i]+list2new[j] for j in range(len(list2new))] for i in range(len(list1))]
print(newList)
# [['foo', 'fooX', 'fooY'], ['bar', 'barX', 'barY'], ['lorem', 'loremX', 'loremY']]

d = deque([0,0,0,1,1,1])
for it in range(2*len(list1)):
    tmp = [newList[i][d[i]] for i in range(len(list1))]
    print(tmp) #
    d.rotate(1)
# ['foo', 'bar', 'lorem']
# ['fooX', 'bar', 'lorem']
# ['fooX', 'barX', 'lorem']
# ['fooX', 'barX', 'loremX']
# ['foo', 'barX', 'loremX']
# ['foo', 'bar', 'loremX']

在此之后,我们可以对 list2 中的其余值重复该过程。

for x in range(1,len(list2new)):
    d = deque([0]*len(list1)+[x]*len(list1))
    d.rotate(1)
    for it in range(2*len(list1)-1): #
        tmp = [newList[i][d[i]] for i in range(len(list1))]
        print(tmp) #
        d.rotate(1)
# ['fooX', 'bar', 'lorem']
# ['fooX', 'barX', 'lorem']
# ['fooX', 'barX', 'loremX']
# ['foo', 'barX', 'loremX']
# ['foo', 'bar', 'loremX']
# ['fooY', 'bar', 'lorem']
# ['fooY', 'barY', 'lorem']
# ['fooY', 'barY', 'loremY']
# ['foo', 'barY', 'loremY']
# ['foo', 'bar', 'loremY']

这将不包含['foo', 'bar', 'lorem'],因此请手动添加。

编辑:好像你编辑了这个问题。要获得所有可能的组合,只需使用newListitertools.product

for c in itertools.product([0,1],repeat=3):
    tmp = [newList[i][c[i]] for i in range(len(c))]
    print(tmp) #

【讨论】:

  • 是的,我想添加我错过的其余组合。现在测试您的解决方案,到目前为止看起来很棒!
  • 您提供的第一个解决方案就像魔术一样!第二个只给了我第一部分(仅适用于“X”)。我想我会选择第一个。非常感谢!
  • 对于第二部分也适用于“Y”,您需要再次重复它,即在itertools.product([0,1],repeat=3) 中将[0,1] 替换为[0,2]。您可以使用另一个 for 循环以编程方式执行此操作
【解决方案2】:

list2 中的每个字符串与空字符串组合,然后将结果与list1 压缩并连接字符串。

from itertools import product

for item in list2:
    for suffixes in product(['', item], repeat=3):
        print([x + s for x, s in zip(list1, suffixes)])

输出:

['foo', 'bar', 'lorem']
['foo', 'bar', 'loremX']
['foo', 'barX', 'lorem']
['foo', 'barX', 'loremX']
['fooX', 'bar', 'lorem']
['fooX', 'bar', 'loremX']
['fooX', 'barX', 'lorem']
['fooX', 'barX', 'loremX']
['foo', 'bar', 'lorem']
['foo', 'bar', 'loremY']
['foo', 'barY', 'lorem']
['foo', 'barY', 'loremY']
['fooY', 'bar', 'lorem']
['fooY', 'bar', 'loremY']
['fooY', 'barY', 'lorem']
['fooY', 'barY', 'loremY']

我在这里打印以在每一行上显示列表,但您可以轻松修改它以将它们附加到另一个列表。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多