2012-08-31 55 views
10

假设我有一个列表:遍历(项目,等等)的列表

l = [0, 1, 2, 3] 

我怎么能遍历目录,以每个项目从列表中的补相处?也就是说,

for item, others in ... 
    print(item, others) 

将打印

0 [1, 2, 3] 
1 [0, 2, 3] 
2 [0, 1, 3] 
3 [0, 1, 2] 

理想我正在寻找一个简洁的表达,我可以在一个修真使用。

回答

13

这是很容易的,可以理解的:

for index, item in enumerate(l): 
    others = l[:index] + l[index+1:] 

可以做一个迭代出来的这个,如果你坚持:

def iter_with_others(l): 
    for index, item in enumerate(l): 
     yield item, l[:index] + l[index+1:] 

给它的用法:

for item, others in iter_with_others(l): 
    print(item, others) 
+0

这工作得很好,这正是ecatmur要求,但似乎无偿列表创作练习。对于更大的列表,它可能表现不佳。我想知道是否最好创建一些包装对象来提供原始列表中的视图。 –

+0

@StevenRumbalski:是的,但除非有巨大的需求,否则我会把它作为读者的练习。 – orlp

3

回答我自己的问题,可以使用itertools.combinations利用结果以字典顺序发出的事实:

from itertools import combinations 
zip(l, combinations(reversed(l), len(l) - 1)) 

但是,这是相当模糊的;爆破的解决方案是很多为读者更容易理解!

2

什么

>>> [(i, [j for j in L if j != i]) for i in L] 
[(0, [1, 2, 3]), (1, [0, 2, 3]), (2, [0, 1, 3]), (3, [0, 1, 2])] 

OK,这是测试和@ nightcracker的解决方案一个极大很可能更有效,但呃...

+0

您可以使用生成器表达式而不是列表解析,从而避免创建不必要的列表,正如@StevenRumbalski梦寐以求的。 –

+0

是的,我可以为整个表达式使用一个生成器,但不能用于内部循环:OP想要打印列表,而不是生成器。 –

+0

对,至少在他的例子中。问题是,这是否真的是他想要的结果。但他可以自己决定。 –