2

我在从字符串和整数列表中仅删除字符串时遇到了一些麻烦。这可能看起来很愚蠢,但这是真的:

>>> A = [1, '2', '3', 4, '5', '4', 6, 56, 7, '4', 6, '543']
>>> 
>>> for i in A:
        if type(i) is str:
                    A.remove(i)


>>> A
[1, '3', 4, 6, 56, 7, '4', 6]

是否有人对正在发生的事情有任何想法,或者我只是做错了什么?

4

6 回答 6

6

或者,您可以使用内置filter函数:

filtered_A = filter(lambda i:not(type(i) is str), A)
于 2013-08-21T08:52:58.173 回答
2

在列表上循环时删除元素不起作用。

改为使用列表推导:

>>> A = [1, '2', '3', 4, '5', '4', 6, 56, 7, '4', 6, '543']
>>> [x for x in A if not isinstance(x, str)]
[1, 4, 6, 56, 7, 6]
于 2013-08-21T08:50:22.997 回答
1

永远不要更改(尤其是添加或删除元素)您正在循环的容器,因为该容器上的迭代器不会被告知您的更改,并且正如您所注意到的,这很可能会产生非常不同的循环和/或一个不正确的。

就像在这种情况下,要从列表中删除的第一个元素是'2'. 在下一次迭代中,循环将适用于A[2],即 now 4。因此,循环永远不会为 element 运行'3'

列表推导是此类情况的最佳选择。

于 2013-08-21T09:07:21.637 回答
0
In [1]: A = [1, '2', '3', 4, '5', '4', 6, 56, 7, '4', 6, '543']

In [2]: [x for x in A if type(x)!=str]
Out[2]: [1, 4, 6, 56, 7, 6]
于 2013-08-21T08:48:36.250 回答
0

不要从您正在循环的列表中删除元素,因为您不会捕获每个元素:

A = [1, '2', '3', 4, '5', '4', 6, 56, 7, '4', 6, '543']

for i in A:
    print(repr(i))
    if type(i) is str:
        A.remove(i)

# 1, '2', 4, '5', 6, 56, 7, '4', '543'

如果您需要显式循环,请复制列表(请参阅教程中有关 for-loop 的部分):

for x in A[:]:
    if isinstance(x, str):
         A.remove(x)

不过,在这种情况下,您应该使用列表推导。

[x for x in A if isinstance(x, int)]
于 2013-08-21T09:00:58.900 回答
0

如果您的意图是在列表中只保留类似数字的对象,那么可以使用以下方法更明确:

A = [1, '2', '3', 4, '5', '4', 6, 56, 7, '4', 6, '543']

from numbers import Number
A[:] = [el for el in A if isinstance(el, Number)]
# [1, 4, 6, 56, 7, 6]

然后,如果你想缩小特定类型的数字(例如,只是整数),你可以这样做:

A = [1, 1.0, 1j]

from numbers import Integral
A[:] = [el for el in A if isinstance(el, Integral)]
# [1]
于 2013-08-21T09:03:19.913 回答