Python 在迭代时修改列表

Python 在迭代时修改列表,python,list,iteration,Python,List,Iteration,我知道在迭代列表时不应该添加/删除项目。但是,如果不更改列表长度,是否可以修改正在迭代的列表中的项目 class Car(object): def __init__(self, name): self.name = name def __repr__(self): return type(self).__name__ + "_" + self.name my_cars = [Car("Ferrari"), Car("Mercedes"), Car

我知道在迭代列表时不应该添加/删除项目。但是,如果不更改列表长度,是否可以修改正在迭代的列表中的项目

class Car(object):
    def __init__(self, name):
        self.name = name
    def __repr__(self):
        return type(self).__name__ + "_" + self.name

my_cars = [Car("Ferrari"), Car("Mercedes"), Car("BMW")]
print(my_cars)  # [Car_Ferrari, Car_Mercedes, Car_BMW]
for car in my_cars:
    car.name = "Moskvich"
print(my_cars)  # [Car_Moskvich, Car_Moskvich, Car_Moskvich]
或者我应该迭代列表索引吗?就像这样:

for car_id in range(len(my_cars)):
    my_cars[car_id].name = "Moskvich"
问题是:上述两种方法都是允许的,还是只有第二种方法是无错误的

如果答案是肯定的,那么以下代码段是否有效

lovely_numbers = [[41, 32, 17], [26, 55]]
for numbers_pair in lovely_numbers:
    numbers_pair.pop()
print(lovely_numbers)  # [[41, 32], [26]]
lovely_numbers = [[41, 32, 17], [26, 55]]
for numbers_pair in lovely_numbers:
    numbers_pair.pop()
print(lovely_numbers)  # [[41, 32], [26]]
UPD。我想看看python文档,它说“这些操作是允许的”,而不是某人的假设。

可以说,您没有修改列表。您只需修改列表中的元素。我不认为这是个问题

要回答第二个问题,两种方法都是允许的(正如您所知,因为您运行了代码),但这取决于具体情况。内容是可变的还是不可变的

例如,如果要向整数列表中的每个元素添加一个,则此操作无效:

>>> x = [1, 2, 3, 4, 5]
>>> for i in x:
...     i += 1
... 
>>> x
[1, 2, 3, 4, 5] 
实际上,
int
s是不可变的对象。相反,您需要迭代索引并在每个索引处更改元素,如下所示:

>>> for i in range(len(x)):
...     x[i] += 1
...
>>> x
[2, 3, 4, 5, 6]

如果您的项目是可变的,那么第一种方法(直接迭代元素而不是索引)无疑更有效,因为额外的索引步骤是可以避免的开销,因为这些元素是可变的。

当然,您可以。第一种方法是正常的,但在某些情况下,您也可以使用或

我知道在迭代列表时不应该添加/删除项目。但是,如果不更改列表长度,是否可以修改正在迭代的列表中的项目

class Car(object):
    def __init__(self, name):
        self.name = name
    def __repr__(self):
        return type(self).__name__ + "_" + self.name

my_cars = [Car("Ferrari"), Car("Mercedes"), Car("BMW")]
print(my_cars)  # [Car_Ferrari, Car_Mercedes, Car_BMW]
for car in my_cars:
    car.name = "Moskvich"
print(my_cars)  # [Car_Moskvich, Car_Moskvich, Car_Moskvich]
您根本没有以任何方式修改列表。您要修改的是列表中的元素;那很好。只要您不直接更改实际列表,您就可以了

不需要迭代索引。事实上,这是不符合实际的。除非您实际上试图更改列表本身,否则只需按值在列表上迭代即可

如果答案是肯定的,那么以下代码段是否有效

lovely_numbers = [[41, 32, 17], [26, 55]]
for numbers_pair in lovely_numbers:
    numbers_pair.pop()
print(lovely_numbers)  # [[41, 32], [26]]
lovely_numbers = [[41, 32, 17], [26, 55]]
for numbers_pair in lovely_numbers:
    numbers_pair.pop()
print(lovely_numbers)  # [[41, 32], [26]]

当然。原因和我上面说的完全一样。您没有修改可爱的数字本身。相反,您只是在修改列表的示例中修改元素,而不是在迭代列表的元素时修改

列出\u迭代期间修改的\u.py

a = [1,2]
i = 0
for item in a:
      if i<5:
          print 'append'
          a.append(i+2)
      print a
      i += 1
a=[1,2]
i=0
对于a中的项目:

如果是,只要你不改变长度,你就不会遇到问题。最后一点是,如果列表在pop之前为空,您将遇到索引器。@dizcza文档也没有提到允许或不允许更改大小。它是。所有这些操作都是允许的,否则会出现语法错误。这是一个风格的问题,也是作为一个好的程序员你不应该做的事情。你已经有两个答案表明修改列表本身不同于修改列表中的元素。这是正确的,但可能让一些人感到困惑。记住列表只包含引用(即指针)可能会有所帮助。为了进一步阅读,我强烈推荐Ned Batchelder。Python确实是按索引列出迭代的,所以是的,在迭代过程中删除项目(除了从末尾删除,使用负切片)是一种潜在的危险行为:在适当的位置修改项目是完全安全的。是的,听起来很合理。我只是想,如果在for循环中,我开始为一个对象创建许多额外的字段(或任何其他操作,这些操作将消耗太多内存,因此需要重新分配),在我完成这个对象并转到下一个对象之前,会发生什么情况。@dizcza在python中,每一位内存都是从堆中分配的。不能保证列表中的相邻元素在实际内存中彼此接近。这绝对不值得担心。:)在for循环运行时,我可以向列表中添加或删除项目。允许吗?如果是这样,python会在for中使用新列表还是原始列表loop@variable这不是个好主意。我只是在循环之外初始化一个新的列表,并相应地添加项目。您给出了一个答案,但没有说明原因,并且在抛出术语和概念,但没有说明它们对OP有何帮助。