从列表中删除值

时间:2018-11-13 10:30:12

标签: python python-3.x list

我有以下问题:

我有一个列表:

temp= [950, 1000, 1100, 1200, 1400, 1450, 1500, 1600, 1650, 1700, 1900, 1950, 2000, 2100, 2200]

在此列表中,我要删除每个< 1200 and > 1950值。

我尝试了以下操作:

for x in temp:
    if x < 1200 or x > 1950:
        temp.remove(x)

这给了我以下结果:

[1000, 1200, 1400, 1450, 1500, 1600, 1650, 1700, 1900, 1950, 2100]

但是我的目标输出如下:

[1200, 1400, 1450, 1500, 1600, 1650, 1700, 1900, 1950]

我找到了一种通过切片完成任务的方法:

new_temp = temp[temp.index(1200):temp.index(1950)+1]

这给了我想要的输出:

[1200, 1400, 1450, 1500, 1600, 1650, 1700, 1900, 1950]

但是我想了解为什么 attemp1 不起作用,并且也许有比 attemp2

更好的方法来完成我的任务

有人可以帮忙吗?预先感谢。

4 个答案:

答案 0 :(得分:2)

您的 attempt1 不起作用,因为您修改了循环的同一列表。这可能会导致各种奇怪的行为,例如跳过某些值。这是一个示例:

>>> lst = [1, 2]
>>> for val in lst:
...     lst.remove(val)
... 
>>> lst
[2]  # wat?

请勿这样做:请勿修改循环显示的列表

记录下来,这是最简单的正确方法(不一定是最快的方法):

result = [value for value in temp if 1200 <= value <= 1950]

还请注意,切片方法temp[temp.index(1200):temp.index(1950)+1]仅在对列表进行排序的前提下有效。在这种假设下,我们可以比任何一种提出的方​​法都快得多。即我们可以进行二进制搜索+切片。但是,除非您处理数百万个值,否则复杂性可能不值得。

答案 1 :(得分:2)

我将创建一个用于识别有效值的函数:

def validated(value):
    return 1200 <= value <= 1950

然后您可以在list comprehension中使用它:

>>> [value for value in temp if validated(value)]
[1200, 1400, 1450, 1500, 1600, 1650, 1700, 1900, 1950]

或者您可以使用filter

>>> list(filter(validated, temp))
[1200, 1400, 1450, 1500, 1600, 1650, 1700, 1900, 1950]

编辑:遇到麻烦的原因是因为您无法修改要迭代的内容。它不“知道”您已将地毯从地毯下面拉出。

另一种方法是复制列表,然后遍历列表。

temp2 = temp[:]  # makes a copy
for x in temp2:
    if x < 1200 or x > 1950:
        temp.remove(x)

此外,remove是线性搜索(很慢)。通常最好做过滤器。如果您确实需要修改temp所引用的列表(而不仅仅是使temp指向其他列表),则可以执行以下操作:

temp[:] = [value for value in temp if validated(value)]

[:]是一个分片运算符,如果您为其指定了分片运算符,它将替换原始列表的全部内容(而不是为名称分配新列表)。

答案 2 :(得分:1)

上面的

@freakish答案是正确的,我只是想使其更清晰。

由于列表迭代而跳过值是此行为的主要问题

请参见下面的循环中的python列表迭代可视化


迭代1

temp= [950, 1000, 1100, 1200, 1400, 1450, 1500, 1600, 1650, 1700, 1900, 1950, 2000, 2100, 2200]

currentIndex = 0(值为 950 的项目)

删除索引为0的元素

进行第二次迭代


迭代2

温度看起来像这样

temp= [1000, 1100, 1200, 1400, 1450, 1500, 1600, 1650, 1700, 1900, 1950, 2000, 2100, 2200]

currentIndex = 1(值为 1100 的项目)

删除索引为1的元素

进行第三次迭代


迭代3

温度看起来像这样

temp= [1000, 1200, 1400, 1450, 1500, 1600, 1650, 1700, 1900, 1950, 2000, 2100, 2200]

currentIndex = 2(值为 1400 的项目)

1400 < 1200,然后转到下一个元素。


我希望应该足够清楚地了解由于这种迭代而发生的事情。为了避免这种行为,请尝试使用其他方法列出exporessions或numpy数组。

答案 3 :(得分:0)

import numpy as np
temp= np.array([950, 1000, 1100, 1200, 1400, 1450, 1500, 1600, 1650, 1700, 1900, 1950, 2000, 2100, 2200])
temp[(temp>=1200) & (temp<=1950)]

输出:

array([1200, 1400, 1450, 1500, 1600, 1650, 1700, 1900, 1950])