2008-08-09

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.append((l[0],item))
resList = resList + genCouples(l[1:])
return resList

7 comments:

  1. 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:]]

    ReplyDelete
  2. zip(*[iter(yourlist)]*2)

    or more explicit:

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

    ReplyDelete
  3. 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)

    ReplyDelete
  4. This comment has been removed by the author.

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

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

    ReplyDelete
  6. @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!

    ReplyDelete
  7. 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

    cheers.

    ReplyDelete