简体   繁体   中英

Generating combinations of values from a list of lists python

I want to get the combinations of a list of list, for example

[['a0', 'a1'], ['b0', 'b1'], ['c0', 'c1', 'c2']]

I can use list(itertools.product(*listOfTuples)) and get

[('a0', 'b0', 'c0'), ('a0', 'b0', 'c1'), ('a0', 'b0', 'c2')... ('a1', 'b1', 'c2')]

How would I get a list with the possible combinations of length 2? For example:

[('a0', 'b0'), ('a0', 'c0'), ('b0', 'c0')...

You can just call itertools.combinations() with r=2 to get all pairs of each triple and then flatten, eg:

In []:
import itertools as it
[t for x in it.product(*s) for t in it.combinations(x, r=2)]

Out[]:
[('a0', 'b0'), ('a0', 'c0'), ('b0', 'c0'), ('a0', 'b0'), ('a0', 'c1'), ('b0', 'c1'),
 ('a0', 'b0'), ('a0', 'c2'), ('b0', 'c2'), ('a0', 'b1'), ('a0', 'c0'), ('b1', 'c0'), 
 ('a0', 'b1'), ('a0', 'c1'), ('b1', 'c1'), ('a0', 'b1'), ('a0', 'c2'), ('b1', 'c2'), 
 ('a1', 'b0'), ('a1', 'c0'), ('b0', 'c0'), ('a1', 'b0'), ('a1', 'c1'), ('b0', 'c1'), 
 ('a1', 'b0'), ('a1', 'c2'), ('b0', 'c2'), ('a1', 'b1'), ('a1', 'c0'), ('b1', 'c0'), 
 ('a1', 'b1'), ('a1', 'c1'), ('b1', 'c1'), ('a1', 'b1'), ('a1', 'c2'), ('b1', 'c2')]

However, this will have duplicates because of ('a0', 'b0', 'c0') , ('a0', 'b0', 'c1') and ('a0', 'b0', 'c2') all generate ('a0', 'b0') , so if you want to remove then you can just use a set , but you lose order:

In []:
{t for x in it.product(*s) for t in it.combinations(x, r=2)}

Out[]:
{('a1', 'c0'), ('b0', 'c1'), ('b0', 'c2'), ('a0', 'c1'), ('a0', 'c2'), ('b1', 'c1'), 
 ('b1', 'c2'), ('a1', 'b1'), ('a1', 'c1'), ('a1', 'c2'), ('b0', 'c0'), ('a0', 'c0'), 
 ('a1', 'b0'), ('b1', 'c0'), ('a0', 'b1'), ('a0', 'b0')}

Sorting it does put it back in order:

In []:
sorted({t for x in it.product(*s) for t in it.combinations(x, r=2)})

Out[]:
[('a0', 'b0'), ('a0', 'b1'), ('a0', 'c0'), ('a0', 'c1'), ('a0', 'c2'), ('a1', 'b0'), 
 ('a1', 'b1'), ('a1', 'c0'), ('a1', 'c1'), ('a1', 'c2'), ('b0', 'c0'), ('b0', 'c1'), 
 ('b0', 'c2'), ('b1', 'c0'), ('b1', 'c1'), ('b1', 'c2')]

You can flatten your list, and create a simple recursive function (for results without repetition in the sublists):

d = [['a0', 'a1'], ['b0', 'b1'], ['c0', 'c1', 'c2']]
def combinations(d, current = []):
  if len(current) == 2:
    yield current
  else:
    for i in d:
      if i not in current:
        yield from combinations(d, current+[i])

print(list(combinations([i for b in d for i in b]))

Output:

[['a0', 'a1'], ['a0', 'b0'], ['a0', 'b1'], ['a0', 'c0'], ['a0', 'c1'], ['a0', 'c2'], ['a1', 'a0'], ['a1', 'b0'], ['a1', 'b1'], ['a1', 'c0'], ['a1', 'c1'], ['a1', 'c2'], ['b0', 'a0'], ['b0', 'a1'], ['b0', 'b1'], ['b0', 'c0'], ['b0', 'c1'], ['b0', 'c2'], ['b1', 'a0'], ['b1', 'a1'], ['b1', 'b0'], ['b1', 'c0'], ['b1', 'c1'], ['b1', 'c2'], ['c0', 'a0'], ['c0', 'a1'], ['c0', 'b0'], ['c0', 'b1'], ['c0', 'c1'], ['c0', 'c2'], ['c1', 'a0'], ['c1', 'a1'], ['c1', 'b0'], ['c1', 'b1'], ['c1', 'c0'], ['c1', 'c2'], ['c2', 'a0'], ['c2', 'a1'], ['c2', 'b0'], ['c2', 'b1'], ['c2', 'c0'], ['c2', 'c1']]

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