简体   繁体   中英

Most efficient way of producing constrained pairs of combinations out of a list in Python

I need to iterate through pairs (a, b) and (c, d) of combinations of length 2, out of a list l of items, with the following constraints:

  1. no repetitions in pairs: if (a, b) already appeared, then (b, a) shall not be produced
  2. no repetitions between pairs, ie, pairs must be considered only once: if (a, b) , (c, d) already appeared, then (c, d) , (a, b) shall not be produced
  3. the items in the two pairs must be different: a != c and a != d and b != c and b != d

For example, with

l = [0, 1, 2, 3, 4]

The pairs should be:

(0, 1), (2, 3)
(0, 1), (2, 4)
(0, 1), (3, 4)

(0, 2), (1, 3)
(0, 2), (1, 4)
(0, 2), (3, 4)

(0, 3), (1, 2)
(0, 3), (1, 4)
(0, 3), (2, 4)

(0, 4), (1, 2)
(0, 4), (1, 3)
(0, 4), (2, 3)

(1, 2), (3, 4)
(1, 3), (2, 4)
(1, 4), (2, 3)

I used integers in the example, however, I am interested in a more general-purpose solution (though the items are lists, in my specific case).

This is the solution I came up with:

import itertools

used = set()

for (a, b) in itertools.combinations(l, 2):
    used.add((a, b))
    for (c, d) in itertools.combinations(l, 2):
        if a == c or a == d or b == c or b == d:
            continue
        if (c, d) in used:
            continue
        # do stuff...
        pass

Apart from looking cumbersome, this solution requires the additional set used . In the actual implementation I used enumerate(l) instead of l and put the indexes of the items in the tuples in the set, and tried to use the indexes to filter the options sooner... but did not manage to make it any better.

How can I make it more efficient and, possibly, more elegant/Pythonic?

An idea could be to first generate all combination of tuples and then to filter them:

l = [0, 1, 2, 3, 4]
aa = list(itertools.combinations(list(itertools.combinations(l, 2)), 2))
[(a,b) for a,b in aa if set(a).isdisjoint(b)]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM