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 _______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor