是否安全(记录行为?)删除执行中迭代器的域

2024-10-02 10:31:20 发布

您现在位置:Python中文网/ 问答频道 /正文

我想知道它是否安全(有记录的行为?)删除Python中执行的迭代器的域空间。你知道吗

考虑代码:

import os
import sys

sampleSpace = [ x*x for x in range( 7 ) ]

print sampleSpace

for dx in sampleSpace:

    print str( dx )

    if dx == 1:

        del sampleSpace[ 1 ]
        del sampleSpace[ 3 ]

    elif dx == 25:

        del sampleSpace[ -1 ]

print sampleSpace

“sampleSpace”就是我所说的“迭代器的域空间”(如果有更合适的词/短语,请告诉我)。你知道吗

我所做的是在迭代器'dx'运行时从中删除值。你知道吗

以下是我对代码的期望:

Iteration versus element being pointed to (*):

0: [*0, 1, 4, 9, 16, 25, 36]
1: [0, *1, 4, 9, 16, 25, 36] ( delete 2nd and 5th element after this iteration )
2: [0, 4, *9, 25, 36]
3: [0, 4, 9, *25, 36] ( delete -1th element after this iteration )
4: [0, 4, 9, 25*] ( as the iterator points to nothing/end of list, the loop terminates )

。。我得到的是:

[0, 1, 4, 9, 16, 25, 36]
0
1
9
25
[0, 4, 9, 25]

如你所见-我所期望的是我得到的-这与我在这种情况下从其他语言得到的行为是相反的。你知道吗

因此,我想问一下,在Python中是否有类似“如果在迭代过程中改变迭代器的空间,那么迭代器将变得无效”这样的规则?你知道吗

是否安全(记录行为?)用Python来做这样的事情?你知道吗


Tags: to代码inimportfor记录空间element
3条回答

你说的安全是什么意思?您的代码碰巧不会引发任何错误,但这是一种明显的可能性,当然,请考虑以下几点:

>>> a = range(3)
>>> for i in a:
    del a


Traceback (most recent call last):
  File "<pyshell#13>", line 2, in <module>
    del a
NameError: name 'a' is not defined
>>> a
[0, 1, 2]
>>> for i in a:
    del a[i+1]


Traceback (most recent call last):
  File "<pyshell#27>", line 2, in <module>
    del a[i+1]
IndexError: list assignment index out of range

不清楚为什么要这样做,但是没有适用于迭代器的附加规则。他们的行为和其他类型的人完全一样。你知道吗

the Python tutorial

It is not safe to modify the sequence being iterated over in the loop (this can only happen for mutable sequence types, such as lists). If you need to modify the list you are iterating over (for example, to duplicate selected items) you must iterate over a copy. The slice notation makes this particularly convenient:

>>> for x in a[:]: # make a slice copy of the entire list
...    if len(x) > 6: a.insert(0, x)
...
>>> a
['defenestrate', 'cat', 'window', 'defenestrate']

一般来说不,这不安全,你可能会有不可预知的行为。在这种情况下,迭代器不需要以特定的方式运行。你知道吗

在你的例子中发生的是

# list is [0, 1, 4, 9, 16, 25, 36]

if dx == 1:
    # we're at index 1 when this is true
    del sampleSpace[ 1 ]
    # we've removed the item at index 1, and the iterator will move to the next valid position - still index 1, but in a mutated list. We got lucky in this case
    # the list now contains [0, 4, 9, 16, 25, 36]
    del sampleSpace[ 3 ]   
    # we remove the item at index 3 which is (now) value 16
    # the list now contains [0, 4, 9, 25, 36]
elif dx == 25:

    del sampleSpace[ -1 ]
    # we remove the final item, list now looks like
    # the list now contains [0, 4, 9, 25]

相关问题 更多 >

    热门问题