Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 两份名单的所有可能替代品?_Python_List_Python 3.x - Fatal编程技术网

Python 两份名单的所有可能替代品?

Python 两份名单的所有可能替代品?,python,list,python-3.x,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] # thir

(我知道问题的标题可能有误导性,但我找不到任何其他方式来表述——请随意编辑)

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

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方法。例如,我可以创建包含2个元素的3个列表,而不是包含3个元素的2个列表;然而,这会使代码过于复杂,如果可以的话,我宁愿避免这种情况


有没有一种简单快捷的方法呢?

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

换句话说,从0迭代到2n-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)]

创建包含两个元素的3个列表不会使代码过于复杂。非常简单(将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)

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

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

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)
其结果是:

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

虽然这是可行的,但我认为没有理由更喜欢它而不是直接获取元素的乘积。计算索引然后建立索引就像对范围内的i(len(someseq))执行
:x=someseq[i]
(并且不再使用
i
),这是Python中由累犯C程序员提交的最直接的反模式之一,速度较慢,灵活性较低(不适用于迭代器),与someseq:@ShadowRanger中的usefulname相比,我同意,我也会直接获得产品。但是我把它放进去了,因为它很容易理解。注意:如果出于某种原因确实想要
list
s,而不是
tuple
s,
output=list(map(list,itertools.product(*zip(a,b)))
tuple
s转换回
list
s,但通常不需要。
[1, 2, 3]
[1, 2, 6]
[1, 5, 3]
[1, 5, 6]
[4, 2, 3]
[4, 2, 6]
[4, 5, 3]
[4, 5, 6]