多维数组完全(除了第一个值)设置为附加值
Multi-dimensional array is entirely (aside the first value) set to appended value
我正在创建一个函数来查找一组给定选项的所有组合。当我将组合作为列表附加到总组合的主列表时(组合是索引,稍后从选项列表中获取),所有现有列表都更改为我刚刚附加的列表,除了第一个.
def allCombos(opts):
limit = len(opts) - 1
combos = []
for n in range(1, 3):
combo = [0] * n
print(combo) # going to remove this
goal = [limit] * n
pointer = 0
overflowed = False
while True:
if combo[pointer] == limit:
pointer += 1
overflowed = True
else:
if overflowed:
combo[pointer] += 1
for i in range(pointer):
combo[i] = 0
pointer = 0
combos.append(combo)
print(combo) # I will change this
else:
combo[pointer] += 1
combos.append(combo)
print(combo) # and this
if combo == goal:
break
allCombos(["foo", "bar"])
产出
[0]
[1]
[0, 0]
[1, 0]
[0, 1]
[1, 1]
而
def allCombos(opts):
limit = len(opts) - 1
combos = []
for n in range(1, 3):
combo = [0] * n
goal = [limit] * n
pointer = 0
overflowed = False
while True:
if combo[pointer] == limit:
pointer += 1
overflowed = True
else:
if overflowed:
combo[pointer] += 1
for i in range(pointer):
combo[i] = 0
pointer = 0
combos.append(combo)
print(combos) # changed
else:
combo[pointer] += 1
combos.append(combo)
print(combos) # changed
if combo == goal:
break
print("\n" + str(combos)) #added
allCombos(["foo", "bar"])
产出
[[1]]
[[1], [1, 0]]
[[1], [0, 1], [0, 1]]
[[1], [1, 1], [1, 1], [1, 1]]
[[1], [1, 1], [1, 1], [1, 1]]
这看起来很奇怪,因为 combos
唯一指定的修改似乎是附加。
我找过其他有类似问题的问题,但没有找到。
提前致谢!
您将对 combo
的多个引用附加到 combos
。当你更改 combo
时,那些引用都指向修改后的列表。与这个简单的例子相比:
>>> x=[1,2]
>>> y=[]
>>> y.append(x)
>>> y.append(x)
>>> y
[[1, 2], [1, 2]]
>>> x[0]+=1
>>> y
[[2, 2], [2, 2]]
>>>
请注意 combo
最初以 [0] 开始,但您永远不会在输出中看到它。那是因为它已更改为 [1]。当您到达循环的顶部时,将 combo
设置为 [0,0]。为什么这不影响 combos
?因为您已将 combo
设置为新值。 combos
中的引用指向与新创建的组合不同的对象。现在开始就地更改 combo
,并将其附加到列表中。你只是得到了同一件事的多个副本。
如果不清楚,请尝试将限制设置为 3 而不是 2。你能预测输出结果是什么吗?
我认为 Gary van der Merwe 提出了一个很好的建议,但我相信他正在考虑 itertools.product
,而不是 itertools.combinations
。
我正在创建一个函数来查找一组给定选项的所有组合。当我将组合作为列表附加到总组合的主列表时(组合是索引,稍后从选项列表中获取),所有现有列表都更改为我刚刚附加的列表,除了第一个.
def allCombos(opts):
limit = len(opts) - 1
combos = []
for n in range(1, 3):
combo = [0] * n
print(combo) # going to remove this
goal = [limit] * n
pointer = 0
overflowed = False
while True:
if combo[pointer] == limit:
pointer += 1
overflowed = True
else:
if overflowed:
combo[pointer] += 1
for i in range(pointer):
combo[i] = 0
pointer = 0
combos.append(combo)
print(combo) # I will change this
else:
combo[pointer] += 1
combos.append(combo)
print(combo) # and this
if combo == goal:
break
allCombos(["foo", "bar"])
产出
[0]
[1]
[0, 0]
[1, 0]
[0, 1]
[1, 1]
而
def allCombos(opts):
limit = len(opts) - 1
combos = []
for n in range(1, 3):
combo = [0] * n
goal = [limit] * n
pointer = 0
overflowed = False
while True:
if combo[pointer] == limit:
pointer += 1
overflowed = True
else:
if overflowed:
combo[pointer] += 1
for i in range(pointer):
combo[i] = 0
pointer = 0
combos.append(combo)
print(combos) # changed
else:
combo[pointer] += 1
combos.append(combo)
print(combos) # changed
if combo == goal:
break
print("\n" + str(combos)) #added
allCombos(["foo", "bar"])
产出
[[1]]
[[1], [1, 0]]
[[1], [0, 1], [0, 1]]
[[1], [1, 1], [1, 1], [1, 1]]
[[1], [1, 1], [1, 1], [1, 1]]
这看起来很奇怪,因为 combos
唯一指定的修改似乎是附加。
我找过其他有类似问题的问题,但没有找到。
提前致谢!
您将对 combo
的多个引用附加到 combos
。当你更改 combo
时,那些引用都指向修改后的列表。与这个简单的例子相比:
>>> x=[1,2]
>>> y=[]
>>> y.append(x)
>>> y.append(x)
>>> y
[[1, 2], [1, 2]]
>>> x[0]+=1
>>> y
[[2, 2], [2, 2]]
>>>
请注意 combo
最初以 [0] 开始,但您永远不会在输出中看到它。那是因为它已更改为 [1]。当您到达循环的顶部时,将 combo
设置为 [0,0]。为什么这不影响 combos
?因为您已将 combo
设置为新值。 combos
中的引用指向与新创建的组合不同的对象。现在开始就地更改 combo
,并将其附加到列表中。你只是得到了同一件事的多个副本。
如果不清楚,请尝试将限制设置为 3 而不是 2。你能预测输出结果是什么吗?
我认为 Gary van der Merwe 提出了一个很好的建议,但我相信他正在考虑 itertools.product
,而不是 itertools.combinations
。