0

According to the question presented here: Python itertools.combinations: how to obtain the indices of the combined numbers, given the following code:

import itertools
my_list = [7, 5, 5, 4]

pairs = list(itertools.combinations(my_list , 2))
#pairs = [(7, 5), (7, 5), (7, 4), (5, 5), (5, 4), (5, 4)]

indexes = list(itertools.combinations(enumerate(my_list ), 2)
#indexes = [(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)]

Is there any way to obtain pairs and indexes in a single line so I can have a lower complexity in my code (e.g. using enumerate or something likewise)?

Maf
  • 696
  • 1
  • 8
  • 23
  • 2
    Just `zip` the two iterators, rather than consuming them into lists. – jonrsharpe Dec 29 '20 at 15:11
  • Could you please help me how to do that? – Maf Dec 29 '20 at 15:12
  • 1
    See https://docs.python.org/3/library/functions.html#zip – jonrsharpe Dec 29 '20 at 15:13
  • Thank you. I'm reading to get the solution ASAP. – Maf Dec 29 '20 at 15:17
  • with `zip (indexes, pairs)` I can get a single list, but I'd like to know if I can have this without having to call `itertools.combinations` twice – Maf Dec 29 '20 at 15:31
  • 1
    I don't think the output from your second example is correct, if you're taking combinations of the tuples from enumerate that would be the values *and* their indices, the first item emitted would be `((0, 7), (1, 5))`. What you show would be the output from combinations of the indices alone, e.g. from `range(len(my_list))`. – jonrsharpe Dec 29 '20 at 15:35
  • Yes. You right. Thanks! – Maf Dec 29 '20 at 15:47

2 Answers2

1

@Maf - try this, this is as @jonsharpe suggested earlier, use zip:

from pprint import pprint
from itertools import combinations

 my_list = [7, 5, 5, 4]
>>> pprint(list(zip(combinations(enumerate(my_list),2), combinations(my_list,2))))
[(((0, 7), (1, 5)), (7, 5)),
 (((0, 7), (2, 5)), (7, 5)),
 (((0, 7), (3, 4)), (7, 4)),
 (((1, 5), (2, 5)), (5, 5)),
 (((1, 5), (3, 4)), (5, 4)),
 (((2, 5), (3, 4)), (5, 4))]
Daniel Hao
  • 4,922
  • 3
  • 10
  • 23
  • We were writing at the same time. It seems to be the best solution. I'm going to to choose your answer. Thanks for answering! – Maf Dec 29 '20 at 15:41
0

(Explicit is better than implicit. Simple is better than complex.) I would use list-comprehension for its flexiblity:

list((x, (x[0][1], x[1][1])) for x in list(combinations(enumerate(my_list), 2)))

This can be further extended using the likes of opertor.itemgetter.

Also, the idea is to run use the iterator only once, so that the method can potentially be applied to other non-deterministic iterators as well, say, an yield from random.choices.

Arnab De
  • 402
  • 4
  • 12