删除列表中与“无”对应的元素

时间:2016-06-13 16:44:01

标签: python

我有两个列表

x = [ None , None , "foo" , "bar" ]
y = [ "bar" , "foo" , "foo" ,"bar"]

len(x) == len(y)

我想检查列表x中是否存在None的元素,然后删除该元素并删除y中的相应元素。 如删除x[0] == None,请从x[0]y[0]

删除xy

结果应该是:

x = ["foo","bar"]
y = ["foo","bar"]

我尝试了一种非常非pythonic的方式,它给了我一个“列表索引超出范围”的错误:

for i in range(0,len(x)):
    if(x[i] == None):
        x.remove(x[i])
        y.remove(y[i])

6 个答案:

答案 0 :(得分:3)

使用zip方法可以非常好地完成此任务:

x, y = zip(*[(e_x, e_y) for e_x, e_y in zip(x, y) if e_x is not None])

在这里,您一次迭代两个列表,创建一个包含x和y元素的元组的新列表。仅当x e_x中的元素不是None时才会添加这些元组。 外部zip将元组列表转换回两个单独的列表。

编辑:正如Donkey Kong在评论中指出的那样,最好使用is not None代替!= None。我相应地更新了代码。

答案 1 :(得分:3)

我们打电话给你的名单xs和ys。

componentWillReceiveProps: function(nextProps) {
        console.log(nextProps);

    },

应该做的伎俩。

答案 2 :(得分:0)

首先查看你需要删除的内容:

remove_ix = {ix for ix, val in enumerate(x) if val is None}

现在您可以使用它来过滤xy

x = [item for ix, item in enumerate(x) if ix not in remove_ix]
y = [item for ix, item in enumerate(y) if ix not in remove_ix]

请注意,对于您的版本,您最终会跳过索引并且可能会IndexError,因为如果列表的初始长度是N并且您删除了单个项目,那么您将会仍然会循环N次,但列表现在是N-1项长。同样使用list.remove,如果存在重复项(您的示例中有),则无法保证删除正确的项目

答案 3 :(得分:0)

我认为实现理想输出的最高效方法是理解。在这种情况下,您应避免避免使用2个列表推导表达式:

x_list = [ None , None , "foo" , "bar" ]
y_list = [ "bar" , "foo" , "foo" ,"bar"]
d = {val:y_list[i] for i,val in enumerate(x_list) if val is not None}
new_l_y = d.values()
new_l_x = d.keys()

注意:您会错过元素的顺序,但保持项目的对应关系。如果订单很重要,您可以使用OrderedDict

from collections import OrderedDict
d = OrderedDict((val,y_list[i]) for i,val in enumerate(x_list) if val is not None)
new_l_y = d.keys()
new_l_y = d.values()

答案 4 :(得分:0)

使用zip从匹配的x和y对中删除None(在x中)的项目,然后使用另一个zip(*...)将列表列表转换回参考x和y:

x, y = zip(*[[ix, iy] for ix, iy in zip(x, y) if ix is not None])

答案 5 :(得分:0)

在死线程中发布答案。它可能会帮助某人。 一种非常简洁的方法是使用itertool的compress方法。

from itertools import compress

x = [None, None, 1, 2]
y = [5, 6, 2, 4]

y = list(compress(y, x))
x = list(compress(x, x))