Reputation: 35
I'm trying to make a function that will take an arbritrary number of dictionary inputs and create a new dictionary with all inputs included. If two keys are the same, the value should be a list with both values in it. I've succeded in doing this-- however, I'm having problems with the dict() function. If I manually perform the dict function in the python shell, I'm able to make a new dictionary without any problems; however, when this is embedded in my function, I get a TypeError. Here is my code below:
#Module 6 Written Homework
#Problem 4
dict1= {'Fred':'555-1231','Andy':'555-1195','Sue':'555-2193'}
dict2= {'Fred':'555-1234','John':'555-3195','Karen':'555-2793'}
def dictcomb(*dict):
mykeys = []
myvalues = []
tupl = ()
tuplist = []
newtlist = []
count = 0
for i in dict:
mykeys.append(list(i.keys()))
myvalues.append(list(i.values()))
dictlen = len(i)
count = count + 1
for y in range(count):
for z in range(dictlen):
tuplist.append((mykeys[y][z],myvalues[y][z]))
tuplist.sort()
for a in range(len(tuplist)):
try:
if tuplist[a][0]==tuplist[a+1][0]:
comblist = [tuplist[a][1],tuplist[a+1][1]]
newtlist.append(tuple([tuplist[a][0],comblist]))
del(tuplist[a+1])
else:
newtlist.append(tuplist[a])
except IndexError as msg:
pass
print(newtlist)
dict(newtlist)
The error I get is as follows:
Traceback (most recent call last):
File "<pyshell#17>", line 1, in <module>
dictcomb(dict1,dict2)
File "C:\Python33\M6HW4.py", line 34, in dictcomb
dict(newtlist)
TypeError: 'tuple' object is not callable
As I described above, in the python shell, print(newtlist) gives:
[('Andy', '555-1195'), ('Fred', ['555-1231', '555-1234']), ('John', '555-3195'), ('Karen', '555-2793')]
If I copy and paste this output into the dict() function:
dict([('Andy', '555-1195'), ('Fred', ['555-1231', '555-1234']), ('John', '555-3195'), ('Karen', '555-2793')])
The output becomes what I want, which is:
{'Karen': '555-2793', 'Andy': '555-1195', 'Fred': ['555-1231', '555-1234'], 'John': '555-3195'}
No matter what I try, I can't reproduce this within my function. Please help me out! Thank you!
Upvotes: 2
Views: 7443
Reputation: 983
Do you need to implement this entirely yourself, or would it be okay to use defaultdict
? If so, you might do something like:
from collections import defaultdict
merged_collection = defaultdict(list)
collection_1= {'Fred':'555-1231','Andy':'555-1195','Sue':'555-2193'}
collection_2= {'Fred':'555-1234','John':'555-3195','Karen':'555-2793'}
for collection in (collection_1, collection_2):
for name, number in collection.items():
merged_collection[name].append(number)
for name, number in merged_collection.items():
print(name, number)
John ['555-3195']
Andy ['555-1195']
Fred ['555-1231', '555-1234']
Sue ['555-2193']
Karen ['555-2793']
Upvotes: 0
Reputation: 208665
You function has a local variable called dict
that comes from the function arguments and masks the built-in dict()
function:
def dictcomb(*dict):
^
change to something else, (*args is the typical name)
Upvotes: 4
Reputation: 99680
A typical example of why keywords should not be used as variable names. Here dict(newtlist)
is trying to call the dict()
builtin python, but there is a conflicting local variable dict
. Rename that variable to fix the issue.
Something like this:
def dictcomb(*dct): #changed the local variable dict to dct and its references henceforth
mykeys = []
myvalues = []
tupl = ()
tuplist = []
newtlist = []
count = 0
for i in dct:
mykeys.append(list(i.keys()))
myvalues.append(list(i.values()))
dictlen = len(i)
count = count + 1
for y in range(count):
for z in range(dictlen):
tuplist.append((mykeys[y][z],myvalues[y][z]))
tuplist.sort()
for a in range(len(tuplist)):
try:
if tuplist[a][0]==tuplist[a+1][0]:
comblist = [tuplist[a][1],tuplist[a+1][1]]
newtlist.append(tuple([tuplist[a][0],comblist]))
del(tuplist[a+1])
else:
newtlist.append(tuplist[a])
except IndexError as msg:
pass
print(newtlist)
dict(newtlist)
Upvotes: 8