Search code examples
pythontuplespython-itertoolsiterableiterable-unpacking

Flatten tuple from iterator in Python


I have a project where I have to iterate over every pair in a list, but also access each item's index. I found this thread, where the suggestion is to use itertools.combinations + enumerate, eg:

>>> mylist = ["a", "b", "c"]
>>> for x, y in itertools.combinations(enumerate(mylist), 2):
...     print(f"x: {x}, y: {y}")

x: (0, 'a'), y: (1, 'b')
x: (0, 'a'), y: (2, 'c')
x: (1, 'b'), y: (2, 'c')

I would like to unpack these so that I can use the index and item separately, eg:

>>> for x, y in itertools.combinations(enumerate(mylist), 2):
...     index_x, item_x = x
...     index_y, item_y = y
...     print(f"index_x: {index_x}, item_x: {item_x}, index_y: {index_y}, item_y: {item_y}")

index_x: 0, item_x: a, index_y: 1, item_y: b
index_x: 0, item_x: a, index_y: 2, item_y: c
index_x: 1, item_x: b, index_y: 2, item_y: c

But is there a way to unpack these inside the loop header? The following:

>>> for index_x, item_x, index_y, item_y in itertools.combinations(enumerate(mylist), 2):
...     print(f"index_x: {index_x}, item_x: {item_x}, index_y: {index_y}, item_y: {item_y}")

Results in: ValueError: not enough values to unpack (expected 4, got 2)


Solution

  • You can do it like this:

    >>> for (index_x, item_x), (index_y, item_y) in itertools.combinations(enumerate(mylist), 2):
    ...     print(f"index_x: {index_x}, item_x: {item_x}, index_y: {index_y}, item_y: {item_y}")
        
    index_x: 0, item_x: a, index_y: 1, item_y: b
    index_x: 0, item_x: a, index_y: 2, item_y: c
    index_x: 1, item_x: b, index_y: 2, item_y: c