0

In Python, I am having 4 lists one and want one of them to become my dictionary key and the rest become my key value, but the list length is different

Employee_ManagerDic = {}
EmployeeID_List = [111,222,333,444,555]
EmployeeFirstName_List = ['a','b','c','d','e']
managerID_List = [888,777,666]
managerFirstName_List = ['f','g','h']

and the output I want is in this format:

Employee_ManagerDic = {EmployeeID_List:[EmployeeFirstName_List,managerID_List,
managerFirstName_List]}

and something like this

Employee_managerDic = {
                       111:['a',888,'f'],
                       222:['b',777,'g'],
                       333:['c',666,'h'],
                       444:['d',null,null],
                       555:['e',null,null]}

I know I may need to use for loop for this but I don't know how to structure the logic of the loop.

Thank you

Alex Hall
  • 34,833
  • 5
  • 57
  • 89
W. Yan
  • 59
  • 1
  • 7

5 Answers5

2

Since you're using python2, you can use itertools.iziplongest and the dict constructor:

from itertools import izip_longest
Employee_managerDic = dict(
    zip(
        EmployeeID_List,
        map(
            list,
            izip_longest(EmployeeFirstName_List, managerID_List, managerFirstName_List)
        )
    )
)
#{111: ['a', 888, 'f'],
# 222: ['b', 777, 'g'],
# 333: ['c', 666, 'h'],
# 444: ['d', None, None],
# 555: ['e', None, None]}

From the docs for iziplongest:

Make an iterator that aggregates elements from each of the iterables. If the iterables are of uneven length, missing values are filled-in with fillvalue.

The intermediate output of list(izip_longest(EmployeeFirstName_List, managerID_List, managerFirstName_List)) is:

[('a', 888, 'f'),
 ('b', 777, 'g'),
 ('c', 666, 'h'),
 ('d', None, None),
 ('e', None, None)]

Then I called map(list, ...) on this to convert the tuples to lists, though this is probably not needed (I just did it to match your desired output).

Finally we pass zip with the EmployeeID_List and this output to the dict constructor.

pault
  • 41,343
  • 15
  • 107
  • 149
  • 2
    The `*` is redundant, just pass the arguments normally. It's also worth noting that this assumes at least one of the lists will be as long as the ID list. – Alex Hall Apr 13 '18 at 19:18
  • I don't think it's important to ensure that the dict values are lists instead of tuples. – Alex Hall Apr 13 '18 at 19:21
  • @AlexHall agreed, and I added a note about that. I just did it to match OP's output. – pault Apr 13 '18 at 19:25
2
from itertools import izip_longest

Employee_ManagerDic = {
    row[0]: row[1:]
    for row in izip_longest(EmployeeID_List,
                            EmployeeFirstName_List,
                            managerID_List,
                            managerFirstName_List)
}

The above is a dictionary comprehension equivalent to:

Employee_ManagerDic = {}
for row in izip_longest(EmployeeID_List,
                        EmployeeFirstName_List,
                        managerID_List,
                        managerFirstName_List):
    Employee_ManagerDic[row[0]] = row[1:]

row[1:] is a slice, in case you're not familiar with that and want to google it.

Alex Hall
  • 34,833
  • 5
  • 57
  • 89
1

For Python2.7 you can use map with None instead of zip, which will give you the longest zip.

>>>map(None, EmployeeID_List, EmployeeFirstName_List, managerID_List, managerFirstName_List) [(111, 'a', 888, 'f'), (222, 'b', 777, 'g'), (333, 'c', 666, 'h'), (444, 'd', None, None), (555, 'e', None, None)]

and then convert to a dictionary using dict comprehension.

result = { tup[0]:tup[1:] for tup in map(None, EmployeeID_List, EmployeeFirstName_List, managerID_List, managerFirstName_List) }

Result:

>>> result {555: ('e', None, None), 444: ('d', None, None), 333: ('c', 666, 'h'), 222: ('b', 777, 'g'), 111: ('a', 888, 'f')}

Note: a result is a dictionary to a tuple. If you want list just replace tup[1:] with list(tup[1:]).

digitake
  • 846
  • 7
  • 16
0
'''
OP has four lists. He wants EmployeeID_List to serve to serve
as the keys in the dict, and he wants the rest of the lists to
serve as the values in the dict key-value pairs. If the indices
in the other lists don't match up, he wants 'Null', or 'NaN'.
'''
#Create the empty dictionary 
Employee_ManagerDic = {}

#Create the EmployeeID_List
EmployeeID_List = [111, 222, 333, 444, 555]

#Create the EmployyeFirstName_List
EmployeeFirstName_List = ['a', 'b', 'c', 'd', 'e']

#Create the managerID_List
managerID_List = [888, 777, 666]

#Create the managerFirstName_List
managerFirstName_List = ['f', 'g', 'h']

#Create a variable to increment the indicies 
num = -1

#Create another variable to increment the indices 
other_num = -1

#Run a for loop loop for EmployeeID_List
#Make the 'item' the dict key
#Make the value the EmployeeFirstName that corresponds
for item in EmployeeID_List:
      num += 1
      Employee_ManagerDic[item] = list(EmployeeFirstName_List[num])


#Check to see if the indicies match in the lists 
how_many_indicies = len(EmployeeID_List) - len(managerID_List)
how_many_indicies2 = len(EmployeeID_List) - len(managerFirstName_List)

#Print the difference in the indicies 
print(how_many_indicies)
print(how_many_indicies2)

#If the indicies don't match, fill the empty space with 'Null'
managerID_List.append('Null')
managerID_List.append('Null')
managerFirstName_List.append('Null')
managerFirstName_List.append('Null')

#Append the values in the other lists to the dictionary lists 
for value in Employee_ManagerDic.values():
       other_num += 1
       value.append(managerID_List[other_num])
       value.append(managerFirstName_List[other_num])

print(Employee_ManagerDic)

Here is the output:

{111: ['a', 888, 'f'], 222: ['b', 777, 'g'], 333: ['c', 666, 'h'], 444: ['d', 'Null', 'Null'], 555: ['e', 'Null', 'Null']}

Here I create variables like num and other_num so that during the for loops we can increment the indices of the list by += 1 each time we run through the loop. I make the dictionary keys the value of the item in the EmployeeID_List as you requested, and then set that value equal to the EmployeeFirstName_List. I increment the index that we want to add as a value from the EmployeeFirstName_List and I use the 'list' function to transform it into a nested list within the dictionary that we created. After that I notice that your other lists have fewer indices, so if you're running a program where users may be missing data, I decided to get the length of the other lists and compare them to the length of the EmployeeID_List. If they differ in length, I append 'Null' to the end of the lists. How many times I append Null to the end of the list depends on how many indices they are missing. Lastly, for each of the values in the dictionary, we append the list item for the other two list to the dictionary list. I append them based off of their index, and each time through the list increment the index. When we print the results, we get the output that you required.

Simeon Ikudabo
  • 2,152
  • 1
  • 10
  • 27
0

It is very easy if you can picture the output in your mind. let say you have three list variables and you want to give them headers(labels) and create a dictionary variable. Let's illustrate it by a sample.

Zipcodes = ['98732','66786','34759']
latitude = ['1.5', '5.6', '3.4']
longitude = ['100.10', '112.4','140.76']
headers = ['Zip Codes', 'latitude', 'longitude']
info = []
info.append(Zipcodes)
info.append(latitude)
info.append(longitude)
Dic = dict(zip(headers, info))
print(Dic)

As you saw, we put all information in one list, and it contains three other list variables. Then we zip the lables and the info, using the "dict" function, and it will give us the dictionary variable.The out put will be:

{'Zip Codes': ['98732', '66786', '34759'], 'latitude': ['1.5', '5.6', '3.4'], 'longitude': ['100.10', '112.4', '140.76']
Ali Taheri
  • 116
  • 3