我的计划是删除所有数字从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”。 这是为什么?
我的计划是删除所有数字从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”。 这是为什么?
我看到两个可能的问题。首先,它是一个范围,而不是实际的阵列。其次,在迭代它的同时修改列表是一个坏主意。使用列表解析来配置。
numbers = [n for n in range(0,1001) if len(str(n)) >= 2]
好点,但是,OP是使用Python 2,其中'范围'返回一个实际的'列表'对象。如果您尝试在Python 3范围内调用'.remove',它会引发'AttributeError:'范围'object has no attribute'remove'' –
当您迭代它时,您不应该更改列表或其他类型的容器。这是发生的那种错误。有关更多详细信息,请参见here。
更确切地说,当您从列表中删除当前或更早的元素,你正在转变其向“左”。由于循环最有可能转化为经典的for
,因此最终会跳过左移的元素。
迭代器不知道底层列表的变化。它只是返回下一个可用的数字,这意味着在删除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]
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]
IIRC,从列表中删除,同时遍历它往往会导致不良的结果。为什么不使用过滤列表理解? – Carcigenicate
要完成@ Carcigenicate的评论:'[我为我在范围内(0,1001)如果len(str(i))> = 2]' –
我试图记住语法来发布答案:0。自从我写了一篇以来,这段时间太长了。 – Carcigenicate