2010-01-11 4 views
9

У меня есть следующий код:Более вещий способ переборе списка, исключая такой элемент каждой итерации

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. «два», «три»
  2. «один», «три»
  3. «один», «два»

Код, который я написал сейчас, кажется немного C++ - ish, есть ли лучшее решение? (Я не хочу хранить все возможные списки в переменной)

EDIT: Я не указал это, но размер списков не обязательно 3. Он может быть любого размера.

EDIT 2: Кажется, есть другое недоразумение: если у меня есть список N, то я хочу N списков размера N-1, каждый из которых не содержит элемент из исходного списка.

РЕДАКТИРОВАТЬ 3: список с 4 пунктов, должны дать этот результат:

  1. 1, 2, 3
  2. 1, 3, 4
  3. 1, 2, 4
  4. 2, 3, 4
+6

Я предсказываю, вы получите десяток ответов на это, 'itertools 'и вызовы генератора будут вызваны, но в итоге не будет предложен ничего лучшего, чем ваш исходный код. –

+0

Нет, он мог бы использовать 'xrange (len (items))'. – Tobu

+0

Нет, он уже использует Python 3 :) –

ответ

17

Хотя upvoted, как сумасшедшие, мое первое решение было не то, что ОП хочет, что 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

Но список, который я написал, был всего лишь примером. На практике он может иметь размер N. – roger

+0

Это гораздо более ясный и понятный, чем исходный код, поэтому я считаю, что он квалифицируется как лучше? По крайней мере, это более питоновское. – donut

+5

На самом деле нет, я хочу перебрать все «комбинации» длины 'N-1'. – roger

5
[items[:i]+items[i+1:] for i in range(len(items))] 

in py2.x использование xrange. очевидно, нарезание все время на большой последовательности не очень эффективно, но это нормально для коротких. Лучшим вариантом было бы использовать itertools.combinations:

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

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

Как и предсказывалось роджер, ответ, который на самом деле не улучшить существующий код :)

a = ["one", "two", "three"] 
for i in range(0, len(a)): 
    print [val[1] for val in enumerate(a) if val[0] != i] 
Смежные вопросы