Python Forum

Full Version: Combining arrays into dict
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi,

I'm trying to create a dictionay combining 2 arrays but I just cannot get it right.
The end result should be: EDITED:
{'in_ledS':0, 'in_ledXL':1, 'in_ledXXL':0, 'in_ledS1':1, 'in_ledS2':1}
I appreciate some help.

#leds status as input
in_ledS = 17      #pin 11
in_ledXL = 18     #pin 12
in_ledXXL = 22    #pin 15
in_ledS1 = 23     #pin 16
in_ledS2 = 4      #pin 7

leds_arry = [in_ledS, in_ledXL, in_ledXXL, in_ledS1, in_ledS2]
leds_state = [0, 1, 0, 1, 1]

def create_dict():
    leds_dict = {}
    for i in range(len(leds_arry)):
        leds_dict[i] = leds_arry[i] + leds_state[i]
    print(leds_state)

   #or

    x = dict(zip(leds_arry, leds_state))
    print(x)
Your example dictionary that you show at the beginning has keys of strings (like "in_ledS"). But your code doesn't have those strings anywhere (variable names are not the same as a string). And the values of those variables don't appear in your example output.

So unless you can say why you need the values of them, I would assume something like this would work:

leds_arry = ["in_ledS", "in_ledXL", "in_ledXXL", "in_ledS1", "in_ledS2"]
leds_state = [0, 1, 0, 1, 1]

x = dict(zip(leds_arry, leds_state))
print(x)
Thanks, I edited the dictionary string.

Actually, that's my problem. leds_arry contains the names of variables. How can I convert them to strings so zip can be used?
Just my take on this:

#leds status as input
in_ledS = 17      #pin 11
in_ledXL = 18     #pin 12
in_ledXXL = 22    #pin 15
in_ledS1 = 23     #pin 16
in_ledS2 = 4      #pin 7

# maybe the values of the pins will change often
# make an array of pin names as strings
leds_arry = ['in_ledS', 'in_ledXL', 'in_ledXXL', 'in_ledS1', 'in_ledS2']
# the present values of the pins as a list
pin_value = [in_ledS, in_ledXL, in_ledXXL, in_ledS1, in_ledS2]
# the present state of the pins
leds_state = [0, 1, 0, 1, 1]
# make an empty dictionary k = pin name, value is a list for pin value and led_state
pin_value_state = {k:[0, 0] for k in leds_arry}

for i in range(len(leds_arry)):
    pin_value_state[leds_arry[i]][0] = pin_value[i]
    pin_value_state[leds_arry[i]][1] = leds_state[i]

for item in pin_value_state.items():
    print(item)
I'm sorry. I don't understand what was edited in the question. The dictionary looks the same to me and the same as the program I gave above creates:

Output:
{'in_ledS': 0, 'in_ledXL': 1, 'in_ledXXL': 0, 'in_ledS1': 1, 'in_ledS2': 1}
If you need the strings, don't store them as separate variables. You haven't shown how they're used, so right now there's no reason to have the variables.

Store the strings in a list or a dict and associate the data you need with them.
Your list does not contain variable names. Nor does you list contain variables. Your list contains 17, 18, 22, 23 and 4. If you were to change in_ledS = 42, leds_array would still contain [17, 18, 22, 23, 4]. When you created the list it referenced the variables to the values that were placed in the array. The list "leds_arry" does not retain any link or relationship to the variables that were used to construct it.

Your function "create_dict()" confuses me. What are you trying to accomplish? If you want a dictionary to map pin numbers to counts, why not just do this:
leds = {17:0, 18:1, 22:0,  23:0, 4:0}
Then you could set all the LEDS like this:
for led, state in leds.items:
    GPIO.output(led, state)
Unfortunately the dictionary isn't very friendly. There is nothing telling use that pin 17 is ledS. To change the LED settings I end up working with the pin numbers.
leds[17] = 0  # Turn ledS off.  Yuck!
What you really need is a way to associate three things. A friendly name, a pin number, and a state. You want a class, but you can also get away with a named tuple.
class LED():
    def __init__(self, pin, state=0):
        self.pin = pin
        self._state = state
        # Additional setup code can go here

    @property
    def state(self):
        '''Return state of LED'''
        return self._state

    @state.setter
    def state(self, value):
        self._state = value
        # Code here to set the state using the pin?

in_ledS = LED(17, 0)
in_ledXL = LED(18, 1)
in_ledXXL = LED(22, 0)
in_ledS1 = LED(23, 1)
in_ledS2 = LED(4, 1)
Now you can use your friendly variable names to turn LED's on and off.
in_ledXL.state = 0
If you want a list of LED's You could make a class for that too.
class LED_array(list):
    @property
    def states(self):
        return [led.state for led in self]

    @states.setter
    def states(self, values):
        for led, value in zip(self, values):
            led.state = values
    
all_leds = [in_ledS, in_ledXL, in_ledXXL, in_ledS1, in_ledS2]
all_leds = [0, 0, 0, 0, 0]
Or if you really just want the dictionary to map nice names to pin numbers you can do something like this:
led_pins = {'in_ledS':17, 'in_led':18, 'in_ledXXL':22, 'in_ledS1':23, 'in_ledS2':24}

for led in led_pins:
    GPIO.output(led, 0)  # Set all LEDS off
GPIO.output(led_pins['in_ledS2'], 1)  # Turn in_ledS2 on
Thank you all for helping and I apologize for not being clear in my post, I was trying to be brief.
This' what I was trying to achieve:
I've a Raspberry controlling some relays and reading the status of some digital lines (GPIO). A bidirectional communication is taken place between the board and the phone's app via mqtt's subscribe/publish.
So, in order for the app to display the info (LEDs ON/OFF) needs to subscribe to a string (dictionary) showing the LED name and its state. The array, leds_state is updated every 2 seconds and the dictionary string is published every 3 seconds.
The code below seems to solve that problem for now.
Thanks again.

def gen_dict_string():
    # set LEDs names
    leds = ["in_ledS", "in_ledXL", "in_ledXXL", "in_ledS1", "in_ledS2"]
    # combine LED name with its state
    pub_dict = dict(zip(leds,leds_state))
    # print(pub_dict)
    return pub_dict
I don't think you need a function. I would generate the dictionary like this.

Map your LED "names" to pin numbers.
leds = {"in_ledS":17, "in_ledXL":18, "in_ledXXL":22, "in_ledS1":23, "in_ledS2":4}
Map your LED "names" to LED status
led_state = {name:GPIO.input(pin) for name, pin in leds.items()}
Or if you got a dictionary of status that you want to apply.
for led, state in led_state.items():
    GPIO.output(leds[led], state)