0

I'm wanting to write a Python script that provides all possible combinations of some variables and arguments but to always include all variables in the results.

I've tried a few attempts but the closest I can get is literally all combinations. For example, let's say a, b, c, d and e can either be true or false. I want all possible combinations but importantly I'm trying to include all of those variables each time. So the following two examples are valid among the results: a:true, b:false, c:false, d:false, e:false a:true, b:true, c:false, d:false, e:false (note b is different)

But the following is NOT what I'm looking for: a:true, c:false

I want all possible combinations but always including a-e.

There is an answer already provided by Martijn Pieters, which is basically what I want minus the requirement that all variables are represented (Find all possible combinations of arguments in Python). Here is the code by Pieters:

from itertools import product

for combo in product((None, True, False), repeat=3):
    arguments = {k: v for k, v in zip('abc', combo) if v is not None}
    print arguments

>>> from itertools import product
>>> for combo in product((None, True, False), repeat=3):
...     arguments = {k: v for k, v in zip('abc', combo) if v is not None}
...     print arguments
... 
{}
{'c': True}
{'c': False}
{'b': True}
{'c': True, 'b': True}
{'c': False, 'b': True}
{'b': False}
{'c': True, 'b': False}
{'c': False, 'b': False}
{'a': True}
{'a': True, 'c': True}
{'a': True, 'c': False}
{'a': True, 'b': True}
{'a': True, 'c': True, 'b': True}
{'a': True, 'c': False, 'b': True}
{'a': True, 'b': False}
{'a': True, 'c': True, 'b': False}
{'a': True, 'c': False, 'b': False}
{'a': False}
{'a': False, 'c': True}
{'a': False, 'c': False}
{'a': False, 'b': True}
{'a': False, 'c': True, 'b': True}
{'a': False, 'c': False, 'b': True}
{'a': False, 'b': False}
{'a': False, 'c': True, 'b': False}
{'a': False, 'c': False, 'b': False}
'''

Ignoring the None option this is almost exactly what I've been trying to do but in this example I wouldn't want to just return that a is false. I would want it to return far fewer combinations because a, b, and c should always be included. It's just the combination of whether they're true or false I want to get from this.

What would be the best way to modify this example to achieve the correct results? Or do you recommend a completely different approach? Many thanks.

Ann
  • 1
  • 2
  • 1
    Just remove the None from the tuple in the first argument of product: for combo in product((True, False), repeat=3). The "if v is not None" is no longer needed on the following line, but leaving it in won't hurt because v will never be None. – Colin Jun 24 '19 at 14:54
  • Isn't this answered here? https://stackoverflow.com/questions/464864/how-to-get-all-possible-combinations-of-a-list-s-elements/5898031#5898031 – Dan H Jun 24 '19 at 20:43

2 Answers2

1

Since this is merely a binary counter, you don't need itertools:

params = "abcd"
N      = len(params)
combos = [{params[p]:n&(1<<p)>0 for p in range(N)} for n in range(1<<N)] 

[{'a': False, 'b': False, 'c': False, 'd': False}, 
 {'a': True,  'b': False, 'c': False, 'd': False}, 
 {'a': False, 'b': True,  'c': False, 'd': False}, 
 {'a': True,  'b': True,  'c': False, 'd': False}, 
 {'a': False, 'b': False, 'c': True,  'd': False}, 
 {'a': True,  'b': False, 'c': True,  'd': False}, 
 {'a': False, 'b': True,  'c': True,  'd': False}, 
 {'a': True,  'b': True,  'c': True,  'd': False}, 
 {'a': False, 'b': False, 'c': False, 'd': True}, 
 {'a': True,  'b': False, 'c': False, 'd': True}, 
 {'a': False, 'b': True,  'c': False, 'd': True}, 
 {'a': True,  'b': True,  'c': False, 'd': True}, 
 {'a': False, 'b': False, 'c': True,  'd': True}, 
 {'a': True,  'b': False, 'c': True,  'd': True}, 
 {'a': False, 'b': True,  'c': True,  'd': True}, 
 {'a': True,  'b': True,  'c': True,  'd': True}]

I have to admit though that using product makes it a bit easier to read (but that may be a matter of opinion):

params = "abcd"
N      = len(params)
combos = [{p:v for p,v in zip(params,c)} for c in product(*[(False,True)]*N)]
Alain T.
  • 40,517
  • 4
  • 31
  • 51
0

Simply remove None from the possible values and repeat by the number of your variable count:

from itertools import product

vars = 'abcde'
for combo in product((True, False), repeat=len(vars)):
    arguments = {k: v for k, v in zip(vars, combo)}
    print( arguments )

Note that if you keep repeat=3, you will only get results for a-c.

As @Colin mentioned, you may remove if v is not None, as the value can never be None in this case.

Output:

{'e': True, 'd': True, 'b': True, 'c': True, 'a': True}
{'e': False, 'd': True, 'b': True, 'c': True, 'a': True}
{'e': True, 'd': False, 'b': True, 'c': True, 'a': True}
{'e': False, 'd': False, 'b': True, 'c': True, 'a': True}
{'e': True, 'd': True, 'b': True, 'c': False, 'a': True}
{'e': False, 'd': True, 'b': True, 'c': False, 'a': True}
{'e': True, 'd': False, 'b': True, 'c': False, 'a': True}
{'e': False, 'd': False, 'b': True, 'c': False, 'a': True}
{'e': True, 'd': True, 'b': False, 'c': True, 'a': True}
{'e': False, 'd': True, 'b': False, 'c': True, 'a': True}
{'e': True, 'd': False, 'b': False, 'c': True, 'a': True}
{'e': False, 'd': False, 'b': False, 'c': True, 'a': True}
{'e': True, 'd': True, 'b': False, 'c': False, 'a': True}
{'e': False, 'd': True, 'b': False, 'c': False, 'a': True}
{'e': True, 'd': False, 'b': False, 'c': False, 'a': True}
{'e': False, 'd': False, 'b': False, 'c': False, 'a': True}
{'e': True, 'd': True, 'b': True, 'c': True, 'a': False}
{'e': False, 'd': True, 'b': True, 'c': True, 'a': False}
{'e': True, 'd': False, 'b': True, 'c': True, 'a': False}
{'e': False, 'd': False, 'b': True, 'c': True, 'a': False}
{'e': True, 'd': True, 'b': True, 'c': False, 'a': False}
{'e': False, 'd': True, 'b': True, 'c': False, 'a': False}
{'e': True, 'd': False, 'b': True, 'c': False, 'a': False}
{'e': False, 'd': False, 'b': True, 'c': False, 'a': False}
{'e': True, 'd': True, 'b': False, 'c': True, 'a': False}
{'e': False, 'd': True, 'b': False, 'c': True, 'a': False}
{'e': True, 'd': False, 'b': False, 'c': True, 'a': False}
{'e': False, 'd': False, 'b': False, 'c': True, 'a': False}
{'e': True, 'd': True, 'b': False, 'c': False, 'a': False}
{'e': False, 'd': True, 'b': False, 'c': False, 'a': False}
{'e': True, 'd': False, 'b': False, 'c': False, 'a': False}
{'e': False, 'd': False, 'b': False, 'c': False, 'a': False}
Mike Scotty
  • 10,530
  • 5
  • 38
  • 50