我有两个列表
x = [ None , None , "foo" , "bar" ]
y = [ "bar" , "foo" , "foo" ,"bar"]
len(x) == len(y)
我想检查列表x
中是否存在None
的元素,然后删除该元素并删除y中的相应元素。
如删除x[0] == None
,请从x[0]
和y[0]
x
和y
结果应该是:
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])
答案 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}
现在您可以使用它来过滤x
和y
:
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))