2017-08-19 57 views
0

我的计划是删除所有数字从0到1000,少于两位数字。 我这样做:为什么不从我的数组中删除这些数字?

numbers = range(0,1001) 
#check for two or more digits 
for number in numbers: 
    if len(str(number)) < 2: 
     numbers.remove(number) 

当我再查我的阵列,它仍包含这些数字 “1,3,5,7,9”。 这是为什么?

+1

IIRC,从列表中删除,同时遍历它往往会导致不良的结果。为什么不使用过滤列表理解? – Carcigenicate

+0

要完成@ Carcigenicate的评论:'[我为我在范围内(0,1001)如果len(str(i))> = 2]' –

+0

我试图记住语法来发布答案:0。自从我写了一篇以来,这段时间太长了。 – Carcigenicate

回答

1

我看到两个可能的问题。首先,它是一个范围,而不是实际的阵列。其次,在迭代它的同时修改列表是一个坏主意。使用列表解析来配置。

numbers = [n for n in range(0,1001) if len(str(n)) >= 2] 
+1

好点,但是,OP是使用Python 2,其中'范围'返回一个实际的'列表'对象。如果您尝试在Python 3范围内调用'.remove',它会引发'AttributeError:'范围'object has no attribute'remove'' –

2

当您迭代它时,您不应该更改列表或其他类型的容器。这是发生的那种错误。有关更多详细信息,请参见here


更确切地说,当您从列表中删除当前或更早的元素,你正在转变其向“左”。由于循环最有可能转化为经典的for,因此最终会跳过左移的元素。

2

迭代器不知道底层列表的变化。它只是返回下一个可用的数字,这意味着在删除0之后,迭代器当前指向1,因此产生2作为下一个要检查的值。简短的回答是:不会修改您正在迭代的列表。

相反,要包含要值一个新的列表保持

numbers = range(0, 1001) 
new_numbers = [] 
for number in numbers: 
    if len(str(number)) >= 2: 
     new_numbers.append(number) 

numbers = new_numbers 

更简单地说,使用列表理解:

numbers = [x for x in numbers if len(str(x)) >= 2] 
0

for循环刚刚生成的索引迭代列表。你正在修改循环内的列表,所以它不会给出正确的结果。

比方说你有LEN列表= 10

numbers = [0,1,2,3,4,5,6,7,8,9] 

并运行这个循环在第一次迭代

for number in numbers: 
    if number < 2: 
     numbers.remove(number) 

,该指数为0,号码为[0,它将删除数字[0] = 0

在第二次迭代中索引将为1,数字列表将为[1 ,2,3,4,5,6,7,8,9],因为我们删除了最后一个l上的第一个元素现在它会删除数字[1] = 2

等等。做你想做什么

最好的办法是使用列表comprehesion:

numbers = [x for x in numbers if len(str(number)) > 2] 
相关问题