我有一个这样的清单:
a_list = [['a', 1], ['b', 4], ['c', None]]
我需要将所有None
值替换为0
,并将任何非None
的值替换为None
。所以上面的列表将成为:
modified_a_list = [['a', None], ['b', None], ['c', 0]]
我有这样的代码:
a_list = [['a', 1], ['b', 4], ['c', None]]
b_list = a_list
modified_a_list = []
for item in b_list:
if item[1]==None:
item[1]=0
modified_a_list.append(item)
else:
item[1] = 0
modified_a_list.append(item)
print a_list, modified_a_list
我的输出变为:
a_list = [['a', None], ['b', None], ['c', 0]]
modified_a_list = [['a', None], ['b', None], ['c', 0]]
modified_a_list
看起来不错。但为什么a_list
也会改变?
答案 0 :(得分:0)
这是列表可变性的问题。当您执行b_list = a_list
时,您只是复制对a_list的引用,因此也会在a_list中对b_list进行更改。然后循环修改b_list中的列表。
由于存在嵌套列表,因此您无法使用切片技巧或其他任何内容复制a_list。最简单的就是使用深度镜:
from copy import deepcopy
a_list = [['a', 1], ['b', 4], ['c', None]]
b_list = deepcopy(a_list)
modified_a_list = []
for item in b_list:
if item[1]==None:
item[1]=0
modified_a_list.append(item)
else:
item[1] = None
modified_a_list.append(item)
print(a_list, modified_a_list)
或者,您可以删除中间人并在循环内部执行内部列表的浅表副本,即:
a_list = [['a', 1], ['b', 4], ['c', None]]
modified_a_list = []
for item in a_list:
temp=item[:]
if item[1]==None:
temp[1]=0
modified_a_list.append(temp)
else:
temp[1] = None
modified_a_list.append(temp)
print(a_list, modified_a_list)
答案 1 :(得分:0)
正如其他人所说,在创建b_list
时,它基本上是指向a_list
的指针。因此,当您使用b_list
时,您也在处理a_list
。如果您想单独留下a_list
,则必须创建一个全新的列表。
>>> a_list = [['a', 1], ['b', 4], ['c', None]]
>>>
>>> modified_a_list = [[a[0], 0 if a[1] is None else None] for a in a_list]
>>>
>>> a_list
[['a', 1], ['b', 4], ['c', None]]
>>>
>>> modified_a_list
[['a', None], ['b', None], ['c', 0]]
答案 2 :(得分:0)
在循环中,item
是b_list
元素的引用,它也引用a_list
。因此,当您在item[1] = 0
中执行b_list
时,它会将item
的第二个元素设置为0,这将反映在列表的两个引用中。
a_list \ \ ----> [ element1, element2, element3 ] / | | | b_list / | | | ['a', 0] ['b', 0] ['c', None]
答案 3 :(得分:0)
你可以试试这个:
a_list = [['a', 1], ['b', 4], ['c', None]]
new_list = [[None if isinstance(b, int) else 0 if b == None else b for b in i] for i in a_list]
输出:
[['a', None], ['b', None], ['c', 0]]