-3

I have two lists in python.

list1 = ['A', 'B']
list2 = [True, False]

list1 has been simplified in the real world it will be more than 2 elements. list 2 will only be true or false.

I'd like to generate the following output, given 2 elements in list1:

output=[
    [['A', True], ['B', True]],
    [['A', False], ['B', True]],
    [['A', True], ['B', False]],
    [['A', False], ['B', False]]]

I'd like the algorithm to be able to support the scenario with more than 2 elements in list1.

Here is an example with 3 elements in list1:

list1 = ['A', 'B', 'C']
list2 = [True, False]

output=[
    [['A', True], ['B', True], ['C', True]],
    [['A', True], ['B', True], ['C', False]],
    [['A', True], ['B', False], ['C', True]],
    [['A', False], ['B', True], ['C', True]],
    [['A', False, ['B', False], ['C', True]],
    [['A', True], ['B', False, ['C', False]],
    [['A', False], ['B', True], ['C', False]],
    [['A', False], ['B', False], ['C', False]]
    ]

The following gets me close but not quite there.

[zip(x, list2) for x in it.permutations(list1, len(list2))]

I know I need to do something using itertools but cannot wrap my head around it. Any advice would be greatly appreciated.

Prune
  • 76,765
  • 14
  • 60
  • 81
Brandon
  • 126
  • 6
  • 1
    The output is ambiguous as it is not a valid list, brackets are not balanced. Please correct it. – Selcuk Nov 01 '19 at 01:27
  • I don't think this is a duplicate, or at least, not a duplicate of the linked question. While the same function (`itertools.product`) needs to be used here, the output desired here is different (a list of lists of lists!) and that means different arguments to `product` need to be used than in the other question. – Blckknght Nov 01 '19 at 17:51
  • Thanks Blckknight I agree with your assessment. Thanks for actually reading things and working with me. Your solution below is the most succinct. – Brandon Nov 02 '19 at 15:50

3 Answers3

1
from pprint import pprint
import itertools

list1 = ['A', 'B']
list2 = [True, False]

newdict = {}
final_list = []
for element in itertools.product(list1,list2):
    if element[0] not in newdict.keys():
        newdict[element[0]] = []
    newdict[element[0]].append(list(element))
values =  (list(newdict.values()))


for x in itertools.product('01', repeat=len(values)):
    tmp_list = []
    for i,index in enumerate(list(x)):
        tmp_list.append(values[int(i)][int(index)])
    final_list.append(tmp_list)

pprint (final_list)

OUTPUT:

[[['A', True], ['B', True]],
 [['A', True], ['B', False]],
 [['A', False], ['B', True]],
 [['A', False], ['B', False]]]

OUTPUT WITH A,B,C:

[[['A', True], ['B', True], ['C', True]],
 [['A', True], ['B', True], ['C', False]],
 [['A', True], ['B', False], ['C', True]],
 [['A', True], ['B', False], ['C', False]],
 [['A', False], ['B', True], ['C', True]],
 [['A', False], ['B', True], ['C', False]],
 [['A', False], ['B', False], ['C', True]],
 [['A', False], ['B', False], ['C', False]]]

Initially I take the cartesian product, but I separate each key (A,B, or C) into its own list. That yields:

[[['A', True], ['A', False]],
 [['B', True], ['B', False]],
 [['C', True], ['C', False]]]

From there we are just counting in binary to index into those list. e.g.

000 = A,True B,True C,True
001 = A,True B,True C,False
...
111 = A,False B,False C,False
ChristSent
  • 11
  • 2
1

You are nearly there with your list comprehension. You just need to use product instead of permutations, since you want to repeat the same values from list2. Try this:

output = [list(zip(list1, x)) for x in itertools.product(list2, repeat=len(list1))]

This creates a list of lists of 2-tuples. If you need the innermost elements to be lists too, you can use list(map(list, zip(...))).

Blckknght
  • 100,903
  • 11
  • 120
  • 169
  • Blckknght you are correct! Thanks for your feedback. I've upvoted but this is the solution I will use moving forward. – Brandon Nov 01 '19 at 14:38
0

I think this would work

import itertools
list1=['A','B']
list2 = [True, False]

output=[]
for a,b in itertools.product(list1,list2):
    temp=[]
    temp.append(a)
    temp.append(b)
    output.append(temp)

print(output)

It is basically permuting everything in list1 with list2

VBhat
  • 1
  • 1