29

Suppose I have two input lists like:

list1 = [1, 2, 3]
list2 = [4, 5, 6]

I want to get a list of lists of tuples, of all the potential combinations between the two - i.e., of ways to pair all the elements up. Thus, the result should be like:

[
    [(1, 4), (2, 5), (3, 6)],
    [(1, 4), (2, 6), (3, 5)],
    [(1, 5), (2, 4), (3, 6)],
    [(1, 5), (2, 6), (3, 4)],
    [(1, 6), (2, 4), (3, 5)],
    [(1, 6), (2, 5), (3, 4)]
]

That is: the first list shows the 1 being paired with the 4, the 2 with the 5, and the 3 with the 6. There are 6 lists, corresponding to all the ways that the elements from list1 could be associated with the elements of list2.

I think the itertools standard library should be helpful here, but I couldn't figure out a solution. I got this far:

list1 = [1, 2, 3]
list2 = [5, 6, 7]
print(list(itertools.product(list1, list2)))

but the result is:

[(1, 5), (1, 6), (1, 7), (2, 5), (2, 6), (2, 7), (3, 5), (3, 6), (3, 7)]

It shows every possible pairing of an element from list1 with an element of list2, but not the possible resulting lists composed from these pairing.

How can I fix the code?

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
GeoJunkie
  • 489
  • 2
  • 5
  • 8
  • 1
    `[[[1,3], [2,4]], [[1,4], [2,3]]]` Why a list of lists of lists? Why not a list of lists? What are the criteria? When does an item go in the 1st or 2nd list? I would expect the expected result to be `[[1,3], [2,4], [1,4], [2,3]]` – Tim Sep 07 '15 at 12:12
  • 1
    That's pretty much what itertools.product is giving me (just a list of tuples instead of a list of list). I'm not trying to find all the possible combinations of items on both lists, but all the possible lists I can produce by merging the two. I'm going to add another edit to try to explain in more plain English instead of just expected code output. – GeoJunkie Sep 07 '15 at 12:17
  • Do you want all the possible interweavings of the two lists? Like what would happen during shuffling of cards. So the example `[1, 2], [3, 4]` would result in the sequences or so: `1 2 3 4 / 1 3 2 4 / 1 3 4 2 / 3 4 1 2 / 3 1 4 2 / 3 1 2 4`. – Dan D. Sep 07 '15 at 12:24
  • Is the order important? – Padraic Cunningham Sep 07 '15 at 12:27
  • Padraic, not necessarily. I can always do sorts on the output list if needed. – GeoJunkie Sep 07 '15 at 12:28
  • Dan, close to it, but there's no assumption that the same values - or even types - are in both lists. (In other words, this should work even if the lists are [1,2] and ['d', 'e']. – GeoJunkie Sep 07 '15 at 12:29
  • If so, see http://stackoverflow.com/questions/15306231/how-to-calculate-all-interleavings-of-two-lists the definition `slot_combinations` computes that result. – Dan D. Sep 07 '15 at 12:42
  • Padraic, it appears there is an issue with what you provided in pastebin. It only outputs pairs, so when list1 = [1, 2, 3, 4] and list2 = [5, 6, 7, 8], then it produces output like: ((1, 5), (1, 6)) ((1, 7), (1, 8)) – GeoJunkie Sep 07 '15 at 12:49
  • Yes, you need * len of the list http://pastebin.com/Bsjx4n6U – Padraic Cunningham Sep 07 '15 at 12:56
  • 1
    what should the output for `list1 = [1, 2, 3];list2 = [5, 6, 7]` be, almost all the answers below return different output than your accepted answer so it is not clear what you actually want, the product or premutations – Padraic Cunningham Sep 07 '15 at 13:03
  • The output from that would be: [[(1, 5), (2, 6), (3, 7)], [(1, 5), (2, 7), (3, 6)], [(1, 6), (2, 5), (3, 7)], [(1, 6), (2, 7), (3, 5)], [(1, 7), (2, 5), (3, 6)], [(1, 7), (2, 6), (3, 5)]] I had the tuples inside coming out as lists in my original request, but that's not really import since I don't need them to be mutable. – GeoJunkie Sep 08 '15 at 16:31

7 Answers7

28

repeat the first list, permutate the second and zip it all together

>>> from itertools import permutations, repeat
>>> a = [1, 2, 3]
>>> b = [4, 5, 6]
>>> list(list(zip(r, p)) for (r, p) in zip(repeat(a), permutations(b)))
[[(1, 4), (2, 5), (3, 6)],
 [(1, 4), (2, 6), (3, 5)],
 [(1, 5), (2, 4), (3, 6)],
 [(1, 5), (2, 6), (3, 4)],
 [(1, 6), (2, 4), (3, 5)],
 [(1, 6), (2, 5), (3, 4)]]

EDIT: As Peter Otten noted, the inner zip and the repeat are superfluous.

[list(zip(a, p)) for p in permutations(b)]
pacholik
  • 8,607
  • 9
  • 43
  • 55
  • It is not clear what it should do if the list are asymmetric. Does it work for you if `b` is the longer? – pacholik Nov 24 '15 at 08:19
  • @AlexLenail I don't see any way to make any sense out of the problem description if the lists can be of different length. I just finished editing the question for clarity, in a way that bakes that assumption in. – Karl Knechtel Mar 02 '23 at 02:19
20

The accepted answer can be simplified to

a = [1, 2, 3]
b = [4, 5, 6]
[list(zip(a, p)) for p in permutations(b)]

(The list() call can be omitted in Python 2)

Peter Otten
  • 414
  • 2
  • 3
13

As @pacholik s answer does not cover lists of different length, here is my solution, using a list comprehension with two variables:

first_list = [1, 2, 3]
second_list = ['a', 'b']

combinations = [(a,b) for a in first_list for b in second_list]

The output looks like this:

[(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b'), (3, 'a'), (3, 'b')]
René Jahn
  • 1,155
  • 1
  • 10
  • 27
  • Which method is the fastest? Like if you have a large list and big sample set. If say 40million combinations which method produces that the fastest? – Jonathan Holloway Sep 16 '17 at 02:23
  • 2
    Covers lists of different lengths but does something completely different. This just produces a product. – pacholik Sep 19 '17 at 19:15
  • you are right, seems like I was too tired while reading the question... – René Jahn Sep 20 '17 at 07:03
  • Why did an answer that is *acknowledged to do something completely different* (and thus **not answer the question at all**) get 15 upvotes? – Karl Knechtel Mar 02 '23 at 01:57
11

Try to use list generator to create the nested lists:

>>> [[[x,y] for x in list1] for y in list2]
[[[1, 3], [2, 3]], [[1, 4], [2, 4]]]
>>>

Or, if you want one-line list, just delete brackets:

>>> [[x,y] for x in list1 for y in list2]
[[1, 3], [1, 4], [2, 3], [2, 4]]
Sdwdaw
  • 1,037
  • 7
  • 14
1

Edited my code to give you your desired output.

list1 = [1,2]
list2 = [3,4]
combined = []

for a in list1:
    new_list = []
    for b in list2:
        new_list.append([a, b])
    combined.append(new_list)

print combined
Joe Smart
  • 751
  • 3
  • 10
  • 28
1

You can create a list by constructing all the permutations of two list members with this, containing the list combinations.

lst1 = [1,2]
lst2 = [3,4]

#lst = [[j,k] for j in lst1 for k in lst2] # [[1,3],[1,4],[2,3],[2,4]]
lst = [[[j,k] for j in lst1] for k in lst2] # [[[1,3],[2,3]],[[1,4],[2,4]]]
print lst
Semih Yagcioglu
  • 4,011
  • 1
  • 26
  • 43
0

Try this:

combos=[]
for i in list1:
      for j in list2:
          combos.append([i,j])
print combos
Matthew Murdoch
  • 30,874
  • 30
  • 96
  • 127
Luke B
  • 2,075
  • 2
  • 18
  • 26
  • 3
    Formatting tip: you can indent your code with 4 extra leading spaces to make it a neat code block like in the other answers. – Lynn Sep 07 '15 at 12:20