2012-04-02 55 views
2

我有两个列表:从两个同步列表中删除相同位置(索引)处的项目?

l1 = ['#', '1', '#', '!'] 
l2 = ['S', 'T', 'K', 'M'] 

如果在L1以“#”我想删除它,并消除任何是在L2相同的位置。 这是我曾尝试(在其他几件事情):

for i in range(len(li[j])): 
    for k in range(len(l2[n])): 
     if j == "#": 
      li.remove([j][i]) 
      l2.remove([n][k]) 

但抱怨说,J是不可定义。 我想要的结果看起来是这样的:

l1 = ['1', '!'] 
l2 = ['T', 'M'] 

我将是提出宝贵意见!

+0

你在哪里设置'j'?什么? – 2012-04-02 10:35:38

+0

'li.remove'它应该是'l1',你的循环变量是'i','k'没有'j',因此'j'没有被定义 – avasal 2012-04-02 10:36:04

回答

1

下面是一个简单,易于理解的方法:

a = ["#", "1", "#", "2", "3", "#"] 
b = ["a", "b", "c", "d", "e", "f"] 

a,b = zip(*[[a[i], b[i]] for i in range(len(a)) if a[i]!="#"]) 
print a 
print b 

个人而言,我觉得它更simplier理解和更有效(读:“更快”)比@jamylak提出的方法。

输出:

>>> 
('1', '2', '3') 
('b', 'd', 'e') 
+0

我不会说这更容易理解比我的方法。您对每个使用的变量重复调用,而我的方法使用内置方法,因此每个变量只需使用一次。名字,例如。过滤器似乎使任何有python经验的人都清楚这个方法。 – jamylak 2012-04-02 11:52:34

+0

@jamylak我是一个Python新手,在我看来,压缩它两次需要比使用简单的生成器更多的处理能力。现在看来我可能是错的,因为内置函数比一段python代码更快。 – bezmax 2012-04-02 11:58:17

+0

当然,虽然python并不总是关于速度。有时我为了可读性牺牲速度,只是为了让代码看起来更好。如果我使用itertools中的所有方法,我可以将zips转换为生成器,并且运行速度会更快,但它会涉及再次将数据转换为列表,这不值得为此示例发布。 – jamylak 2012-04-02 12:02:51

0

由于您总是在两个列表中访问相同的索引,所以一个循环就足够了,但是当列表长度不一样时,您需要小心。

而且从列表中删除,同时遍历它是容易出错的,下面的解决方案存储在清除列表所有指数,并从两个列表中的第二去删除索引:

l1 = ['#', '1', '#', '!']  
l2 = ['S', 'T', 'K', 'M'] 
remove = [] 
for i in range(len(l1) - 1): 
    if l1[i] == '#': 
     remove.insert(0, i) 

for i in remove: 
    l1.pop(i) 
    l2.pop(i) 

for i in l1: 
    print i 
for i in l2: 
    print i 
6
>>> l1 = ['#', '1', '#', '!'] 
>>> l2 = ['S', 'T', 'K', 'M'] 

>>> l1,l2 = zip(*((x,y) for x,y in zip(l1,l2) if x!='#')) 
>>> l1 
('1', '!') 
>>> l2 
('T', 'M') 

使用filter

>>> l1,l2 = zip(*filter(lambda x: '#' not in x,zip(l1,l2))) 
>>> l1 
('1', '!') 
>>> l2 
('T', 'M') 

使用itertools

>>> from itertools import compress 
>>> l1,l2 = zip(*compress(zip(l1,l2),(x!='#' for x in l1))) 
>>> l1 
('1', '!') 
>>> l2 
('T', 'M') 
相关问题