Dolda2000 的回答很好地涵盖了主要问题,但这里还有其他三个问题。
index(n)
在循环中使用for n in a
几乎总是一个坏主意。
这是不正确的:
a = [1, 2, 1, 2]
for n in a:
print(a.index(n))
这将打印0
, 然后1
,然后0
再打印。为什么?嗯,第三个值是1
。是列表a.index(1)
中第一个的索引。1
那是0
,不是2
。
它也很慢:要找到i
th 值,您必须检查i
列表中的第一个元素。这将一个简单的线性(快速)算法变成了一个二次(慢)算法。
幸运的是,Python 有一个很好的工具来做你想做的事enumerate
:
for i, n in enumerate(a):
print(i)
或者,如果您根本不需要这些值,只需索引:
for i in len(range(a)):
print(i)
(这在文档中至少出现了两次提示,方便地埋在新手不会看到的地方。但它也在教程的早期进行了说明。)
接下来,您似乎正在尝试测试 Dolda2000 解释的确切情况,如下所示:
n is a[a.index(n)]
为什么那行不通?您证明它们是同一个对象,那么为什么删除它没有做任何事情呢?
与 C 系列语言不同,变量是存储值(包括对其他地址的引用)的地址,Python 变量是您绑定到在其他地方单独存在的值的名称。所以变量不能引用其他变量,但它们可以是相同值的名称。该is
表达式测试两个表达式是否命名相同的值。因此,您证明了您有两个名称具有相同的值,您删除了其中一个名称,但另一个名称和值仍然存在。
一个例子值 1000 字,所以运行这个:
a = object() # this guarantees us a completely unique value
b = a
print a, b, id(a), id(b), a is b
del b
print a, id(a)
(当然,如果你也del a
,那么在某些时候 Python会删除该值,但你看不到,因为根据定义,你不再有任何名称可以用来查看它。)
显然,我可以在迭代时从列表中删除。
嗯,有点。Python 未定义当您在迭代一个可迭代对象时对其进行变异时会发生什么——但它确实有一种特殊的语言来描述文档中内置可变序列(这意味着list
)和s (我不记得在哪里,但它在某处说它不能保证提高 a ,这意味着它应该提高 a )。for
dict
RuntimeError
RuntimeError
因此,如果您知道这a
是一个list
,而不是某个子类list
或第三方序列类,您可以在迭代时从中删除,并且如果您要删除的元素位于或到,则可以预期“跳过”行为迭代器的左边。但是很难想出这些知识的实际用途。