Generate all the couples

Is there a more pythonic way to generate all the couples (unordered) that this?

def genCouples(l):
"""returns a list of couples (item1, item2) with all the pairs from l"""
resList = []
if len(l) > 1:
for item in l[1:]:
resList = resList + genCouples(l[1:])
return resList


Marius Gedminas said...

Blogger is really bad at posting code examples in comments, but here goes:

def genCouples(seq):
    return [(x, y) for i, x in enumerate(seq) for y in seq[i+1:]]

madduck said...


or more explicit:

it = iter(yourlist); zip(it, it)

Matt Draisey said...

How about unrolling the recursion and generating a sequence instead of a list

def genCouples(l):
items = list(l)
while len(items) > 1:
fst = items.pop(0)
for snd in items:
yield (fst,snd)

jgarrett said...
This comment has been removed by the author.
jgarrett said...

Depending on what's in the list, I like...

[(x,y) for x in l for y in l if x < y]

Sandro Tosi said...

@Marius: that was exactly what I wanted to do, but I didn't know enumerate, so got on recursion; before I wrote "return [(x,y) for x in seq for y in seq]" but that's return all the tuples (ordered) not the sets (unordered couples). (ah, btw: I was reading your blog the last day ;) )

@madduck: thanks, but your code solve another problem :) it groups up the list in couples (for l=range(4) it returns [(0, 1), (2, 3)]), but I need all the couples that one can generate from the given list (so for l=range(4) I need [(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)])

@Matt: thanks, I was exploring even this way, but I think the Python Way is using lists generation.

@jgarrett: wow, even more compact! For me should be enough, since I got strings to compoare.

@ALL: thanks a lot for the collaboration!

Clinton said...

In the interest of showing you yield:

def couples(list):
. for (i, a) in enumerate(list):
. . for b in list[i+1:]:
. . . yield (a, b)

for couple in couples(range(4)):
. print couple