两个清单的所有可能替换?

时间:2017-06-16 16:09:10

标签: python list python-3.x

(我知道问题的标题可能会产生误导,但我找不到任何其他方式来制定它 - 随意编辑它)

我有两个相同长度的列表:

a = [1,2,3]
b = [4,5,6]

我想用第二个列表获取第一个列表的所有可能替换。

output[0] = [1,2,3] # no replacements
output[1] = [4,2,3] # first item was replaced
output[2] = [1,5,3] # second item was replaced
output[3] = [1,2,6] # third item was replaced
output[4] = [4,5,3] # first and second items were replaced
output[5] = [4,2,6] # first and third items were replaced
output[6] = [1,5,6] # second and third items were replaced
output[7] = [4,5,6] # all items were replaced

请注意,以下问题无法解答此问题:

涉及先前链接的答案的可能解决方案是创建多个列表,然后对它们使用 itertools.product 方法。例如,我可以创建3个2个元素的列表,而不是2个3个元素的列表。但是,这会使代码过于复杂,如果可以,我宁愿避免这样做。

有一种简单快捷的方法吗?

3 个答案:

答案 0 :(得分:3)

每个项目可以单独更换或单独保留。这可以通过1或0来建模。如果您认为每个项都是一个单独的位,那么迭代所有可能性可以映射到迭代 n 位的所有组合

换句话说,迭代从0到2 n -1并查看位模式。

n = len(a)
for i in range(2**n):
    yield [a[j] if i & (1 << j) != 0 else b[j] for j in range(n)]

将其断开,i & (1 << j) != 0检查 i j 是否已设置。如果是,请使用a[j],否则使用b[j]

结果:

[1, 2, 3]
[4, 2, 3]
[1, 5, 3]
[4, 5, 3]
[1, 2, 6]
[4, 2, 6]
[1, 5, 6]
[4, 5, 6]

答案 1 :(得分:3)

创建3个两个元素的列表根本不会使代码过于复杂。 zip can "flip the axes" of multiple lists非常简单(将Y元素的X序列转换为X元素的Y序列),使其易于使用itertools.product

import itertools

a = [1,2,3]
b = [4,5,6]

# Unpacking result of zip(a, b) means you automatically pass
# (1, 4), (2, 5), (3, 6)
# as the arguments to itertools.product
output = list(itertools.product(*zip(a, b)))

print(*output, sep="\n")

哪个输出:

(1, 2, 3)
(1, 2, 6)
(1, 5, 3)
(1, 5, 6)
(4, 2, 3)
(4, 2, 6)
(4, 5, 3)
(4, 5, 6)

与您的示例输出不同的顺序,但它是同一组可能的替换。

答案 2 :(得分:0)

好的,这与其他答案类似,但从中取一点。您可以将问题建模为查找给定长度序列的所有可能位,并仅在有1时替换,否则不替换。

with open(USER_DATA,'r') as file:
        f = encodeutils.safe_encode(file.read().encode('utf-8'))
        init_script = base64.b64encode(f).decode('utf-8')

所有位组合均为:

from itertools import product

a = [1,2,3]
b = [4,5,6]

## All binary combinations of length of a (or b)
combinations = product([0,1], repeat=len(a))

for combination in combinations:
    y = []
    for l, i in zip(zip(a,b),combination):
         y.append(l[i])
    print y

结果是:

(0, 0, 0)
(0, 0, 1)
(0, 1, 0)
(0, 1, 1)
(1, 0, 0)
(1, 0, 1)
(1, 1, 0)
(1, 1, 1)