一种更加pythonic的方式迭代列表,同时每次迭代排除一个元素

时间:2010-01-11 14:20:04

标签: python

我有以下代码:

items = ["one", "two", "three"]

for i in range(0, len(items)):
    for index, element in enumerate(items):
        if index != i:
            # do something with element

基本上我想要排除每个元素一次并迭代其余元素。所以对于我上面的列表,我想要以下迭代:

  1. “two”,“three”
  2. “one”,“three”
  3. “one”,“two”
  4. 我现在编写的代码似乎有点C ++ - 是的,有更好的解决方案吗? (我不想在变量中保存所有可能的列表)

    编辑:我没有说明这一点,但列表大小不一定是3.它可以是任何大小。

    编辑2:似乎还有另一个误解:如果我有一个N的列表,那么我想要N个大小为N-1的列表,每个列表都缺少原始列表中的元素。

    编辑3:包含4个项目的列表应该给出这个结果:

    1. 1,2,3
    2. 1,3,4
    3. 1,2,4
    4. 2,3,4

3 个答案:

答案 0 :(得分:17)

尽管疯狂地投票,但我的第一个解决方案并不是OP想要的,这是 N个列表,每个都缺少N个原始元素中的一个:

>>> from itertools import combinations
>>> L = ["one", "two", "three", "four"]
>>> for R in combinations(L, len(L) - 1):
...     print " and ".join(R)
...
one and two and three
one and two and four
one and three and four
two and three and four

有关以下讨论的来源,请参阅revision history

答案 1 :(得分:5)

[items[:i]+items[i+1:] for i in range(len(items))]
py2.x中的

使用xrange。显然,在一个大序列上一直切片并不是很有效,但对于短序列来说这很好。更好的选择是使用itertools.combinations

>>> for a in itertools.combinations(items, len(items)-1):
    print(a)

('one', 'two')
('one', 'three')
('two', 'three')

答案 2 :(得分:1)

正如罗杰预测的那样,答案并没有真正改善现有代码:)

a = ["one", "two", "three"]
for i in range(0, len(a)):
  print [val[1] for val in enumerate(a) if val[0] != i]