Consider a list : [A,B,C,D]
I have to find the fastest way split the list in all possible sets of pairs such that the pairs are mutually exclusive: For example, for the given list, the result should be:
{[A,B],[C,D]}
{[A,C],[B,D]}
{[A,D],[B,C]}
Consider a list : [A,B,C,D]
I have to find the fastest way split the list in all possible sets of pairs such that the pairs are mutually exclusive: For example, for the given list, the result should be:
{[A,B],[C,D]}
{[A,C],[B,D]}
{[A,D],[B,C]}
Simple recursive version:
def all_pairings(l):
if len(l) == 0:
return [[]]
else:
return [[(l[0],l[i])] + p for i in range(1,len(l)) for p in all_pairings(l[1:i]+l[i+1:])]
all_pairings('')
# [[]]
all_pairings('ab')
# [[('a', 'b')]]
all_pairings('abcd')
# [[('a', 'b'), ('c', 'd')], [('a', 'c'), ('b', 'd')], [('a', 'd'), ('b', 'c')]]
all_pairings('abcdef')
# [[('a', 'b'), ('c', 'd'), ('e', 'f')], [('a', 'b'), ('c', 'e'), ('d', 'f')],
# [('a', 'b'), ('c', 'f'), ('d', 'e')], [('a', 'c'), ('b', 'd'), ('e', 'f')],
# [('a', 'c'), ('b', 'e'), ('d', 'f')], [('a', 'c'), ('b', 'f'), ('d', 'e')],
# [('a', 'd'), ('b', 'c'), ('e', 'f')], [('a', 'd'), ('b', 'e'), ('c', 'f')],
# [('a', 'd'), ('b', 'f'), ('c', 'e')], [('a', 'e'), ('b', 'c'), ('d', 'f')],
# [('a', 'e'), ('b', 'd'), ('c', 'f')], [('a', 'e'), ('b', 'f'), ('c', 'd')],
# [('a', 'f'), ('b', 'c'), ('d', 'e')], [('a', 'f'), ('b', 'd'), ('c', 'e')],
# [('a', 'f'), ('b', 'e'), ('c', 'd')]]
map
or a list comprehension to iterate on the result of all_pairings
. Assuming your values are in a dict called d={('a','b'): 10, ('c','d'):20, ('a','c'):30, ...}
, then you can write result = [sum(d[pair] for pair in pairing) for pairing in all_pairings('abcd')]
–
Butcherbird all_pairings
is a recursive function, so it could give a recursion error if called on a list too long. But if all_pairing(lst)
alone doesn't give a recursion error, then [sum(d[pair] for pair in pairing) for pairing in all_pairings(lst)]
shouldn't give a recursion error either. –
Butcherbird all_pairings
exactly the way I wrote it in my answer, then iterate on the return of all_pairings the way I shown in my comment. Do not try to mix the two. –
Butcherbird else:
should be return [d[(l[0],l[i])] + p for i in range(1,len(l)) for p in all_pairings(l[1:i]+l[i+1:])]
, where d
is the dictionary. But again, I advise against it. –
Butcherbird © 2022 - 2024 — McMap. All rights reserved.
itertools
which provide this functionality. – Questionless