Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combinations of two non-consecutive items

Given a list, how can I get all combinations between two non-consecutive items?

For example, for input [1, 2, 3, 4, 5] how can I get the output [(1,3), (1,4), (1,5), (2,4), (2,5), (3,5)]?

I'm not interested in (1,2), (2,3), (3,4) or (4,5) because they are consecutive (i.e. next to each other) in the list, but everything else I'm interested.

What's the most idiomatic way to do this in Python?

like image 989
fabiomaia Avatar asked Nov 05 '16 13:11

fabiomaia


2 Answers

A simple list comprehension:

>>> lst = [1, 2, 3, 4, 5]
>>> [(a, b) for i, a in enumerate(lst) for b in lst[i+2:]]
[(1, 3), (1, 4), (1, 5), (2, 4), (2, 5), (3, 5)]
like image 51
Stefan Pochmann Avatar answered Sep 30 '22 10:09

Stefan Pochmann


Here is a fairly "idiomatic" way not using any modules, which is more efficient than some other implementations since every trip through the loop is used--no rejected possibilities.

r = [1, 2, 3, 4, 5]
c = [(r[i], r[j]) for i in range(len(r)-2) for j in range(i+2, len(r))]
print(c)

This gives

[(1, 3), (1, 4), (1, 5), (2, 4), (2, 5), (3, 5)]

It is not completely idiomatic, since it loops on indices rather than values, but your restriction regarding the positions in the list rather than the values makes that fairly necessary. If you want a generator rather than a list, replace the outer brackets with parentheses.

like image 43
Rory Daulton Avatar answered Sep 30 '22 10:09

Rory Daulton