Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Iterate over (item, others) in a list

Suppose I have a list:

l = [0, 1, 2, 3]

How can I iterate over the list, taking each item along with its complement from the list? That is,

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

would print

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

Ideally I'm looking for a concise expression that I can use in a comprehension.

like image 553
ecatmur Avatar asked Aug 31 '12 20:08

ecatmur


3 Answers

This is quite easy and understandable:

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

You could make an iterator out of this if you insist:

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

Giving it's usage:

for item, others in iter_with_others(l):
    print(item, others)
like image 74
orlp Avatar answered Oct 19 '22 07:10

orlp


Answering my own question, it is possible to use itertools.combinations exploiting the fact that the result is emitted in lexicographical order:

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

However, this is fairly obscure; nightcracker's solution is a lot easier to understand for the reader!

like image 3
ecatmur Avatar answered Oct 19 '22 07:10

ecatmur


What about

>>> [(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, that's a gazillion of tests and @nightcracker's solution is likely more efficient, but eh...

like image 2
Pierre GM Avatar answered Oct 19 '22 08:10

Pierre GM