For loop to delete项目正在影响错误的列表 - Python

时间:2015-01-12 15:46:15

标签: python python-2.7

我需要创建一个包含ID的日期列表和一个不包含ID的日期列表。 for循环正在without_ids上运行,那么为什么两个print with_ids语句会产生不同的结果(第1列缺失)?

import datetime
with_ids = [[u'ID 1', datetime.datetime(2014, 12, 9, 0, 0), datetime.datetime(2015, 2, 17, 0, 0), datetime.datetime(2015, 3, 4, 0, 0), datetime.datetime(2015, 3, 13, 0, 0)], [u'ID 2', datetime.datetime(2014, 12, 9, 0, 0), datetime.datetime(2015, 2, 17, 0, 0), datetime.datetime(2015, 3, 4, 0, 0), datetime.datetime(2015, 3, 13, 0, 0)]]
print with_ids
without_ids = with_ids
for x in without_ids:
    del x[0]
print "\n"
print with_ids

输出:

[[u'ID 1', datetime.datetime(2014, 12, 9, 0, 0), datetime.datetime(2015, 2, 17, 0, 0), datetime.datetime(2015, 3, 4, 0, 0), datetime.datetime(2015, 3, 13, 0, 0)], [u'ID 2', datetime.datetime(2014, 12, 9, 0, 0), datetime.datetime(2015, 2, 17, 0, 0), datetime.datetime(2015, 3, 4, 0, 0), datetime.datetime(2015, 3, 13, 0, 0)]]


[[datetime.datetime(2014, 12, 9, 0, 0), datetime.datetime(2015, 2, 17, 0, 0), datetime.datetime(2015, 3, 4, 0, 0), datetime.datetime(2015, 3, 13, 0, 0)], [datetime.datetime(2014, 12, 9, 0, 0), datetime.datetime(2015, 2, 17, 0, 0), datetime.datetime(2015, 3, 4, 0, 0), datetime.datetime(2015, 3, 13, 0, 0)]]

2 个答案:

答案 0 :(得分:1)

without_ids = with_ids

由于with_ids引用了一个列表,without_ids将不会引用相同的列表。因此,当您从without_ids删除项目时,您将删除基础列表对象中的项目,该列表对象与with_ids仍在引用的列表相同。因此,对引用同一对象的所有变量都会显示对同一对象的所有更改。

您必须创建列表的副本,而不是复制引用。通常,你会这样做:

without_ids = with_ids[:]

但是,这只会复制外部列表,使其成为浅层副本。由于您的列表包含列表列表,因此您需要深层复制。在那一点上,它变得有点单调乏味。

因此,您可以创建一个新列表,而不是创建一个副本,而只包含您要保留的元素

without_ids = [elem[1:] for elem in with_ids]

这是一个列表推导,它将迭代with_ids中的所有元素,只选择除第一个之外的所有子列表元素(elem[1:]表示从第一个索引开始,然后取出所有内容) ,并从那些新的列表。

答案 1 :(得分:1)

声明

without_ids = with_ids

您正在without_ids引用与with_ids相同的对象(这称为别名)。

你能做什么?你可以制作一个deep copy(一个简单的副本with_ids[:]不会起作用,因为它是一个嵌套列表):

import copy
without_ids = copy.deepcopy(with_ids)