[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