2013-08-01 22 views
4

我有三个列表:过滤两份名单同时

del_ids = [2, 4] 
ids = [3, 2, 4, 1] 
other = ['a', 'b', 'c', 'd'] 

,我的目标是消除del_ids,结果是

ids = [3, 1] 
other = ['a', 'd'] 

我试图做一个面具元素,以保持(mask = [id not in del_ids for id in ids] ),我打算在这两个列表上应用此掩码。

但我觉得这不是一个pythonic解决方案。你能告诉我怎样才能做得更好吗?

回答

8

拉链,过滤并再次解压缩:

ids, other = zip(*((id, other) for id, other in zip(ids, other) if id not in del_ids)) 

zip()呼叫对每个id与相应other元件,发电机表达滤除其中iddel_ids被列出的任何一对,并且zip(*..)然后引子再次将剩余的对放入单独的列表中。

演示:

>>> del_ids = [2, 4] 
>>> ids = [3, 2, 4, 1] 
>>> other = ['a', 'b', 'c', 'd'] 
>>> zip(*((id, other) for id, other in zip(ids, other) if id not in del_ids)) 
[(3, 1), ('a', 'd')] 
+0

感谢您的回答,您可以告诉我的明星是什么,在这种情况呢?这种形式的理解对我来说是新的。 :O –

+0

@BarnabasSzabolcs:它将序列(来自生成器表达式的所有对)作为单独的参数应用于'zip()'函数。 'zip()'见'zip(pair1,pair2,pair3等)',然后将所有这些对拉成两个列表。 –

+0

@BarnabasSzabolcs:'(.. for .. in ..)'构造是一个生成器表达式。这很像列表理解('[.. for .. in ..]'),除非它不会在内存中首先创建一个新列表。 –

1

压缩,过滤器,解压:

ids, other = zip(*filter(lambda (id,_): not id in del_ids, zip(ids, other))) 
+0

@Martijn:过滤器返回一个正好2元组的过滤列表,所以我可以安全地解压它们。该死的你是对的,我做了更正。 –

+0

是的,直到您的过滤器返回多于或少于2个元组。不要复制我的解决方案,直到你明白它的作用。 :-P –

+0

@MartijnPieters:我在看过你之前写了答案。我想伟大的思想家都认为一样; --P –