[Tutor] Help with unnamed arguments in a merge function

Colin Corr pythonlists at hardcorr.net
Tue Mar 22 05:57:54 CET 2005


On Wed, 2005-03-16 at 02:45 -0500, Brian van den Broek wrote:
> Colin Corr said unto the world upon 2005-03-16 01:38:
> > Greetings Tutors,
> > 
> > I am having some difficulties with the concept of functions which can
> > accept an unnamed number of arguments. Specifically, when trying to
> > write a function that deals with an unnamed number of dictionaries. I
> > want to be able to merge any number of dictionaries, while preserving
> > the values (ie. cannot use update()). 
> > 
> > ~I would appreciate any help that can point in me in the right
> > direction, without directly providing me the answer.~
> > 
> > I understand how to accomplish this task with named arguments:
> > 
> > def mergedicts(firstdict, seconddict):
> >     '''merges two dictionaries into a single dictionary, and converts
> > duplicate key values to a list'''
> >     newdict = firstdict.copy()
> >     for key in seconddict.keys():
> >         if key in firstdict.keys():
> >             newdict[key] = firstdict[key], seconddict[key]
> >             newdict[key] = list(newdict[key])
> >         else:
> >             newdict[key] = seconddict[key]
> >     
> >     return newdict
> > 
> > 
> > dict1 = {'1':'a','2':'b','3':'c'}
> > dict2 = {'4':'d','5':'e','6':'f','1':'g'}
> > somedicts1 = mergedicts(dict1,dict2)
> > print somedicts1
> > 
> > #returns: {'1': ['a', 'g'], '3': 'c', '2': 'b', '5': 'e', '4': 'd', '6':
> > 'f'}
> > 
> > I also think I understand how to use unnamed arguments to merge lists:
> > 
> > def mergelists(*somelists):
> >     '''merges multiple lists into a single list and consolidates lists
> > elements'''
> >     mergedict = {}
> >     for element in somelists:
> >         for unique in element:
> >             mergedict[unique] = 1
> >     combolist = mergedict.keys()
> >     
> >     return combolist
> >             
> > Where I am getting hung up is that, if I do this with unnamed arguments
> > for dictionaries:
> > 
> > def mergedicts(*somedicts):
> > 
> > I get an: AttributeError: 'tuple' object has no attribute 'keys'
> > 
> > 
> > However, I run into the same problem when trying with one named, and
> > unnamed.
> > 
> > def mergedicts2(firstdict,*somedicts):
> >     '''merges any number of dictionaries into a single dictionary, and
> > converts duplicate key values to a list'''
> >     merged = firstdict.copy()
> >     for key in somedicts.keys():
> >         if key in merged.keys():
> >             merged[key] = merged[key], somedicts[key]
> >             merged[key] = list(merged[key])
> >         else:
> >             merged[key] = somedicts[key]
> > 
> >     return merged
> > 
> > Based on my understanding of how unnamed arguments work in functions: I
> > think the dictionaries are being converted into a tuple of all of the
> > dictionary values, and I cannot make a working copy of the first
> > dictionary passed to the function, with the named example. Should I then
> > unpack the resulting tuple into corresponding first,second,third...
> > dictionaries for further processing? 
> > 
> > I am also wondering if this is even the right approach? Can this be done
> > with only unnamed arguments, or do I at least need to name the first
> > argument for the first reference dictionary, and then use an *unnamed
> > for each additional dictionary?  
> > 
> > 
> > Thanks for any pointers,
> > 
> > Colin
> 
> Hi Colin,
> 
> The problem is that somedicts is indeed a tuple -- having *args in a 
> function def collects non-positional, non-keyword arguments into a 
> tuple. So, in your function body, somedicts is a tuple of dicts. (It's 
> not that each dict is somehow tuplized.)
> 
> See if this helps:
> 
>  >>> def print_values(*some_dicts):
> ... 	for a_dict in some_dicts:
> ... 		for key in a_dict:
> ... 			print a_dict[key]
> ...
>  >>> d1 = {1:2, 3:4}
>  >>> d2 = {1:42, 2:84}
>  >>> print_values(d1, d2)
> 2
> 4
> 42
> 84
> 
> Best,
> 
> Brian vdB
> 

Hi Brian,

Thanks for the quick response to my post. And my apologies for the
delayed gratitude. You helped me to confirm my thoughts on the problem,
and I now have a fresh perspective on how to solve it... though I
haven't had the time to get back to it yet.

Thanks again,

Colin




More information about the Tutor mailing list