Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Combining arrays into dict
#1
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)
Reply
#2
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)
ebolisa likes this post
Reply
#3
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?
Reply
#4
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)
Reply
#5
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.
Reply
#6
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
ebolisa likes this post
Reply
#7
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
Reply
#8
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)
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Sort a dict in dict cherry_cherry 4 62,288 Apr-08-2020, 12:25 PM
Last Post: perfringo

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020