一个列表中的 .pop() 和 .append() 影响另一个列表?
.pop() and .append() from one list affecting a different list?
我在 Python 中做一些组合学的事情并得到了一个奇怪的效果。我创建了几个列表,从一个列表中弹出,将结果附加到另一个列表中——但是 third 列表的一个已经存在的条目正在以某种方式被更改。
def cycle( theList ):
cycleList = []
if len(theList) < 3:
return theList
for ii in range( len(theList) - 2 ):
cycleList.append([
theList[ii],
theList[ii + 1],
theList[ii + 2] ])
return cycleList
Combos = [[1, 2, 3, 4, 5], [1, 3, 2, 4, 5]]
for combo in Combos:
listA = []
listB = []
fromListA = [x for x in combo]
fromListB = [fromListA[0]]
listA.append( cycle(fromListA) )
listB.append( cycle(fromListB) )
for jj in range(1, len(combo) - 1):
print("List B's first entry: " + str(listB[0]) )
fromListB.append( fromListA.pop( len(fromListA) - 1 ))
print("List B's first entry: " + str(listB[0]) )
break
break
这是输出:
>>> execfile('test.py')
List B's first entry: [1]
List B's first entry: [1, 5]
>>>
最近一直在学习C++,所以想找个奇怪的参考资料之类的...
...但这是 Python.
编辑:该死的!它是一个参考问题。
要复制列表,可以使用
listA = list(listB)
或
listA = listB[:]
问题在行-
listB.append( cycle(fromListB) )
如果 theList 的长度小于 3,循环函数直接 returns 'theList'。 fromListB 就是这种情况,因此 ListB 的第一个元素是对 fromListB 的引用,并且当你花到 fromListB ,它也反映在 ListB 的第一个元素中。
您的问题出在 cycle()
函数中。
def cycle( theList ):
cycleList = []
if len(theList) < 3: # <<< PROBLEM IS HERE <<<<<
return theList # <<<<< PROBLEM IS HERE <<<<<
for ii in range( len(theList) - 2 ):
cycleList.append([
theList[ii],
theList[ii + 1],
theList[ii + 2] ])
return cycleList
当您在外部 for
循环中执行 fromListB = [fromListA[0]]
时,fromListB
的长度为 1。然后,当您执行 listB.append( cycle(fromListB) )
时,cycle(fromListB)
最终会返回您传入的相同列表,因此 listB[0]
现在指向与 fromListB
.
相同的列表
现在,当您在内部 for
循环中执行 fromListB.append( fromListA.pop( len(fromListA) - 1 ))
时,您正在修改 listB[0]
指向的同一个列表。
顺便说一下,相关位是 fromListB.append('ANYTHING')
,而不是你从 fromListA
弹出的事实。
我在 Python 中做一些组合学的事情并得到了一个奇怪的效果。我创建了几个列表,从一个列表中弹出,将结果附加到另一个列表中——但是 third 列表的一个已经存在的条目正在以某种方式被更改。
def cycle( theList ):
cycleList = []
if len(theList) < 3:
return theList
for ii in range( len(theList) - 2 ):
cycleList.append([
theList[ii],
theList[ii + 1],
theList[ii + 2] ])
return cycleList
Combos = [[1, 2, 3, 4, 5], [1, 3, 2, 4, 5]]
for combo in Combos:
listA = []
listB = []
fromListA = [x for x in combo]
fromListB = [fromListA[0]]
listA.append( cycle(fromListA) )
listB.append( cycle(fromListB) )
for jj in range(1, len(combo) - 1):
print("List B's first entry: " + str(listB[0]) )
fromListB.append( fromListA.pop( len(fromListA) - 1 ))
print("List B's first entry: " + str(listB[0]) )
break
break
这是输出:
>>> execfile('test.py')
List B's first entry: [1]
List B's first entry: [1, 5]
>>>
最近一直在学习C++,所以想找个奇怪的参考资料之类的...
...但这是 Python.
编辑:该死的!它是一个参考问题。
要复制列表,可以使用
listA = list(listB)
或
listA = listB[:]
问题在行-
listB.append( cycle(fromListB) )
如果 theList 的长度小于 3,循环函数直接 returns 'theList'。 fromListB 就是这种情况,因此 ListB 的第一个元素是对 fromListB 的引用,并且当你花到 fromListB ,它也反映在 ListB 的第一个元素中。
您的问题出在 cycle()
函数中。
def cycle( theList ):
cycleList = []
if len(theList) < 3: # <<< PROBLEM IS HERE <<<<<
return theList # <<<<< PROBLEM IS HERE <<<<<
for ii in range( len(theList) - 2 ):
cycleList.append([
theList[ii],
theList[ii + 1],
theList[ii + 2] ])
return cycleList
当您在外部 for
循环中执行 fromListB = [fromListA[0]]
时,fromListB
的长度为 1。然后,当您执行 listB.append( cycle(fromListB) )
时,cycle(fromListB)
最终会返回您传入的相同列表,因此 listB[0]
现在指向与 fromListB
.
现在,当您在内部 for
循环中执行 fromListB.append( fromListA.pop( len(fromListA) - 1 ))
时,您正在修改 listB[0]
指向的同一个列表。
顺便说一下,相关位是 fromListB.append('ANYTHING')
,而不是你从 fromListA
弹出的事实。