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

rog*_*ger 9 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
Run Code Online (Sandbox Code Playgroud)

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

  1. "二三"
  2. "一","三"
  3. "一二"

我现在编写的代码似乎有点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

bal*_*pha 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
Run Code Online (Sandbox Code Playgroud)

请参阅以下讨论源的修订历史记录.

  • 实际上不,我想迭代长度为"N-1"的所有"组合". (5认同)

Sil*_*ost 5

[items[:i]+items[i+1:] for i in range(len(items))]
Run Code Online (Sandbox Code Playgroud)

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

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

('one', 'two')
('one', 'three')
('two', 'three')
Run Code Online (Sandbox Code Playgroud)