pythonc0der
pythonc0der

Reputation: 33

Using recursion to build a dictionary

I'm trying to write a dictionary containing every combination of boolean vales True and False for x amount of variables. So far - I have done this a long-winded way and I know I could make this easier with recursion but I am confused as to how I could do this. If anyone can give me any help to modify this code it would be great please.

    def vars(self) : 
        return self.left.vars() | self.right.vars()             

    def dict(self):
        if len(self.vars()) > 0 :
            d = {i : True for i in self.vars() }
            d1 = {i : False for i in self.vars() }
            if len(self.vars()) > 1 :
                d2 = d.copy()
                d2[list(self.vars())[1]] = False
                d3 = d1.copy()
                d3[list(self.vars())[1]] = True
                if len(self.vars()) > 2 : 
                    d4 = d2.copy()
                    d4[list(self.vars())[2]] = False
                    d5 = d4.copy()
                    d5[list(self.vars())[1]] = True
                    d6 = d3.copy()
                    d6[list(self.vars())[2]] = True
                    d7 = d6.copy()
                    d7[list(self.vars())[1]] = False
                    return [d, d1, d2, d3, d4, d5, d6, d7]
                return [d, d1, d2, d3]
            return [d, d1]

So my return looks something like this...

[{'x': True}, {'x': False}]

for one variable, and for 3 it's

[{'r': True, 'p': True, 'q': True},
 {'r': False, 'p': False, 'q': False},
 {'r': True, 'p': False, 'q': True},
 {'r': False, 'p': True, 'q': False},
 {'r': True, 'p': False, 'q': False},
 {'r': True, 'p': True, 'q': False},
 {'r': False, 'p': True, 'q': True},
 {'r': False, 'p': False, 'q': True}]

the self.vars() returns a set of variables in an expression - in my code this only goes as far as 3 variables hence my code for the dictionary only goes up to 3 variables but I know I should be able to do it for any amount of variables.

I should probably have some for loop and call on my function to add to the dictionary, I'm just unsure how to implement this.

Edit: I can not import different functions to do this

Upvotes: 1

Views: 148

Answers (3)

thebjorn
thebjorn

Reputation: 27321

The simplest way is to realize that getting all the combinations is the same as counting in binary, where each binary digit corresponds to a variable:

def combinations(vars):
    dicts = []
    for i in range(2 ** len(vars)):  # each binary digit represents a variable
        binarystr = bin(i)[2:].zfill(len(vars))   # '0b10101' => '000010101'
        dicts.append(dict(zip(vars, [digit == '1' for digit in binarystr])))
    return dicts

sample run:

>>> combinations(['a', 'b'])
[{'b': False, 'a': False}, {'b': True, 'a': False}, {'b': False, 'a': True}, {'b': True, 'a': True}]
>>> combinations(['a', 'b', 'c'])
[{'b': False, 'c': False, 'a': False}, {'b': False, 'c': True, 'a': False}, {'b': True, 'c': False, 'a': False}, {'b': True, 'c': True, 'a': False}, {'b': False, 'c': False, 'a': True}, {'b': False, 'c': True, 'a': True}, {'b': True, 'c': False, 'a': True}, {'b': True, 'c': True, 'a': True}]

Upvotes: 1

amir askari
amir askari

Reputation: 61

hello you need to see binary to solve that:

def dict(self):
    list_of_dict=[]
    for i in range(2**len(self.vars)):
        my_dict={}
        for j in range(len(self.vars)):   # 0 for false and 1 for true (we have 2^self.vars)
            if ((i >> j) % 2)==0:
                my_dict[list(self.vars())[j]]=False
            else:
                my_dict[list(self.vars())[j]]=True
        list_of_dict.append(my_dict)
    return list_of_dict
    

Upvotes: 1

Daren
Daren

Reputation: 114

For a start, you can try this:

from itertools import product

bools = [[True, False]] * 3  # Or any other value
list(product(*v))

[(True, True, True),
 (True, True, False),
 (True, False, True),
 (True, False, False),
 (False, True, True),
 (False, True, False),
 (False, False, True),
 (False, False, False)]

Attaching the variable names to each bool and converting each to dictionaries should be simple!

Upvotes: 0

Related Questions