Re: [Tutor] adding dictionary values
2009/3/20 Kent Johnson > 2009/3/20 Emad Nawfal (عماد نوفل) : > > > if I want to do this with more than two dictionaries, the obvious > solution > > for me is to use something like the reduce functions with a list of > > dictionary names like: > > dictList = [dict1, dict2, dict3] > > newDict = reduce(addDicts, dictList) > > > > Is this a satisfactory solution? > > This will do some extra copying, as addDicts() always copies the first > argument. You would do better with something like > def addToDict(a, b): >for k,v in b.iteritems(): >a[k] += v > return a > > newDict = reduce(addDictTo, dictList[1:], defaultdict(int, dictList[0])) > > or rewrite addDicts() to take a variable number of arguments and loop > over the args. > > Kent > Thanks Kent and All. I appreciate your helpfulness -- لا أعرف مظلوما تواطأ الناس علي هضمه ولا زهدوا في إنصافه كالحقيقة.محمد الغزالي "No victim has ever been more repressed and alienated than the truth" Emad Soliman Nawfal Indiana University, Bloomington ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] adding dictionary values
2009/3/20 Emad Nawfal (عماد نوفل) : > if I want to do this with more than two dictionaries, the obvious solution > for me is to use something like the reduce functions with a list of > dictionary names like: > dictList = [dict1, dict2, dict3] > newDict = reduce(addDicts, dictList) > > Is this a satisfactory solution? This will do some extra copying, as addDicts() always copies the first argument. You would do better with something like def addToDict(a, b): for k,v in b.iteritems(): a[k] += v return a newDict = reduce(addDictTo, dictList[1:], defaultdict(int, dictList[0])) or rewrite addDicts() to take a variable number of arguments and loop over the args. Kent ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] adding dictionary values
On Fri, Mar 20, 2009 at 12:03 PM, Richard Lovely wrote: > 2009/3/20 Chris Fuller : > > You should iterate over the keys of the dictionary: > > for k in a.keys(): > > because if you iterate over the full dictionary, your items are the > values, > > not the keys. Otherwise your code looks correct, and I don't think its > > terribly bad form. You could do something interesting with sets: > > sa = set(a.keys()) > > sb = set(b.keys()) > > > > The next step could be a for loop, but if you enjoy terseness and taking > > advantage of language features (also should be faster for big enough > dicts): > > c = dict( \ > > [(k, a[k]+b[k]) for k in sa&sb ] + \ > > [(k, a[k]) for k in sa-sb ] + \ > > [(k, b[k]) for k in sb-sa ] > > ) > > > > which creates a new dict from a list of key, value pairs. The list is a > sum > > of three lists: those keys in both a and b, those only in a, and those > only > > in b. > > > > Cheers > > > > On Friday 20 March 2009 10:11, Emad Nawfal wrote: > >> Hi Tutors, > >> I have two pickled dictionaries containing word counts from two > different > >> corpora. I need to add the values, so that a word count is the sum of > both. > >> If the word "man" has a count of 2 in corpus A and a count of 3 in > corpus > >> B, then I need a new dictionary that has "man": 5. Please let me know > >> whether the following is correct/incorrect, good/bad, etc. > >> Your help appreciated: > >> > >> def addDicts(a, b): > >> c = {} > >> for k in a: > >> if k not in b: > >> c[k] = a[k] > >> else: > >> c[k] = a[k] + b[k] > >> > >> for k in b: > >> if k not in a: > >> c[k] = b[k] > >> return c > >> > >> # test this > >> dict1 = {"dad": 3, "man": 2} > >> dict2 = {"dad": 5, "woman": 10} > >> newDict = addDicts(dict1, dict2) > >> print(newDict) > >> # This gives > >> > >> {'dad': 8, 'woman': 10, 'man': 2} > > ___ > > Tutor maillist - Tutor@python.org > > http://mail.python.org/mailman/listinfo/tutor > > > > Just to add another tool to your toolbox, defaultdicts, available from > version 2.5, are good for word counts, and simplifies your function no > end: > > from collections import defaultdict > def addDict(a, b): >newdict = defaultdict(int, a) >for k,v in b.iteritems(): >newdict[k] += v >return newdict > > you can chage the last line to "return dict(newdict)" if the returned > value MUST be a dict, but there is very little advantage to doing so > in properly written code. > > Extra credit: > To do a word count with a defaultdict is simple: > wordcount = defaultdict(int) > for word in list_of_words: >wordcount[word] += 1 > > Look it up in the docs if you want details of defaultdict. > -- > Richard "Roadie Rich" Lovely, part of the JNP|UK Famile > www.theJNP.com > ___ > Tutor maillist - Tutor@python.org > http://mail.python.org/mailman/listinfo/tutor > Thanks All for the help, if I want to do this with more than two dictionaries, the obvious solution for me is to use something like the reduce functions with a list of dictionary names like: dictList = [dict1, dict2, dict3] newDict = reduce(addDicts, dictList) Is this a satisfactory solution? -- لا أعرف مظلوما تواطأ الناس علي هضمه ولا زهدوا في إنصافه كالحقيقة.محمد الغزالي "No victim has ever been more repressed and alienated than the truth" Emad Soliman Nawfal Indiana University, Bloomington ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] adding dictionary values
2009/3/20 Chris Fuller : > You should iterate over the keys of the dictionary: > for k in a.keys(): > because if you iterate over the full dictionary, your items are the values, > not the keys. Otherwise your code looks correct, and I don't think its > terribly bad form. You could do something interesting with sets: > sa = set(a.keys()) > sb = set(b.keys()) > > The next step could be a for loop, but if you enjoy terseness and taking > advantage of language features (also should be faster for big enough dicts): > c = dict( \ > [(k, a[k]+b[k]) for k in sa&sb ] + \ > [(k, a[k]) for k in sa-sb ] + \ > [(k, b[k]) for k in sb-sa ] > ) > > which creates a new dict from a list of key, value pairs. The list is a sum > of three lists: those keys in both a and b, those only in a, and those only > in b. > > Cheers > > On Friday 20 March 2009 10:11, Emad Nawfal wrote: >> Hi Tutors, >> I have two pickled dictionaries containing word counts from two different >> corpora. I need to add the values, so that a word count is the sum of both. >> If the word "man" has a count of 2 in corpus A and a count of 3 in corpus >> B, then I need a new dictionary that has "man": 5. Please let me know >> whether the following is correct/incorrect, good/bad, etc. >> Your help appreciated: >> >> def addDicts(a, b): >> c = {} >> for k in a: >> if k not in b: >> c[k] = a[k] >> else: >> c[k] = a[k] + b[k] >> >> for k in b: >> if k not in a: >> c[k] = b[k] >> return c >> >> # test this >> dict1 = {"dad": 3, "man": 2} >> dict2 = {"dad": 5, "woman": 10} >> newDict = addDicts(dict1, dict2) >> print(newDict) >> # This gives >> >> {'dad': 8, 'woman': 10, 'man': 2} > ___ > Tutor maillist - tu...@python.org > http://mail.python.org/mailman/listinfo/tutor > Just to add another tool to your toolbox, defaultdicts, available from version 2.5, are good for word counts, and simplifies your function no end: from collections import defaultdict def addDict(a, b): newdict = defaultdict(int, a) for k,v in b.iteritems(): newdict[k] += v return newdict you can chage the last line to "return dict(newdict)" if the returned value MUST be a dict, but there is very little advantage to doing so in properly written code. Extra credit: To do a word count with a defaultdict is simple: wordcount = defaultdict(int) for word in list_of_words: wordcount[word] += 1 Look it up in the docs if you want details of defaultdict. -- Richard "Roadie Rich" Lovely, part of the JNP|UK Famile www.theJNP.com ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] adding dictionary values
2009/3/20 greg whittier : > This looks like it will work, but you can accomplish this more compactly by > just looping over the items in both dictionaries and making use of the > default argument of the dictionaries get method. > > newDict = {} > for k, v in dict1.items() + dict2.items(): > newDict[k] = newDict.get(k,0) + v Even simpler, start with a copy of dict1: newDict = dict(dict1) for k, v in dict2.items(): newDict[k] = newDict.get(k,0) + v Kent ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] adding dictionary values
Oops! The dictionary iterates over keys, not values as I stated (and demonstrated by your working code). Consequently, the example I gave could be more succinctly expressed by: sa = set(a) sb = set(b) Sorry for the error. Cheers ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] adding dictionary values
You should iterate over the keys of the dictionary: for k in a.keys(): because if you iterate over the full dictionary, your items are the values, not the keys. Otherwise your code looks correct, and I don't think its terribly bad form. You could do something interesting with sets: sa = set(a.keys()) sb = set(b.keys()) The next step could be a for loop, but if you enjoy terseness and taking advantage of language features (also should be faster for big enough dicts): c = dict( \ [(k, a[k]+b[k]) for k in sa&sb ] + \ [(k, a[k]) for k in sa-sb ] + \ [(k, b[k]) for k in sb-sa ] ) which creates a new dict from a list of key, value pairs. The list is a sum of three lists: those keys in both a and b, those only in a, and those only in b. Cheers On Friday 20 March 2009 10:11, Emad Nawfal wrote: > Hi Tutors, > I have two pickled dictionaries containing word counts from two different > corpora. I need to add the values, so that a word count is the sum of both. > If the word "man" has a count of 2 in corpus A and a count of 3 in corpus > B, then I need a new dictionary that has "man": 5. Please let me know > whether the following is correct/incorrect, good/bad, etc. > Your help appreciated: > > def addDicts(a, b): > c = {} > for k in a: > if k not in b: > c[k] = a[k] > else: > c[k] = a[k] + b[k] > > for k in b: > if k not in a: > c[k] = b[k] > return c > > # test this > dict1 = {"dad": 3, "man": 2} > dict2 = {"dad": 5, "woman": 10} > newDict = addDicts(dict1, dict2) > print(newDict) > # This gives > > {'dad': 8, 'woman': 10, 'man': 2} ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] adding dictionary values
2009/3/20 Emad Nawfal (عماد نوفل) > Hi Tutors, > I have two pickled dictionaries containing word counts from two different > corpora. I need to add the values, so that a word count is the sum of both. > If the word "man" has a count of 2 in corpus A and a count of 3 in corpus B, > then I need a new dictionary that has "man": 5. Please let me know whether > the following is correct/incorrect, good/bad, etc. > Your help appreciated: > > def addDicts(a, b): > c = {} > for k in a: > if k not in b: > c[k] = a[k] > else: > c[k] = a[k] + b[k] > > for k in b: > if k not in a: > c[k] = b[k] > return c > > # test this > dict1 = {"dad": 3, "man": 2} > dict2 = {"dad": 5, "woman": 10} > newDict = addDicts(dict1, dict2) > print(newDict) > # This gives > > {'dad': 8, 'woman': 10, 'man': 2} > > This looks like it will work, but you can accomplish this more compactly by just looping over the items in both dictionaries and making use of the default argument of the dictionaries get method. newDict = {} for k, v in dict1.items() + dict2.items(): newDict[k] = newDict.get(k,0) + v ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] adding dictionary values
Hi Tutors, I have two pickled dictionaries containing word counts from two different corpora. I need to add the values, so that a word count is the sum of both. If the word "man" has a count of 2 in corpus A and a count of 3 in corpus B, then I need a new dictionary that has "man": 5. Please let me know whether the following is correct/incorrect, good/bad, etc. Your help appreciated: def addDicts(a, b): c = {} for k in a: if k not in b: c[k] = a[k] else: c[k] = a[k] + b[k] for k in b: if k not in a: c[k] = b[k] return c # test this dict1 = {"dad": 3, "man": 2} dict2 = {"dad": 5, "woman": 10} newDict = addDicts(dict1, dict2) print(newDict) # This gives {'dad': 8, 'woman': 10, 'man': 2} -- لا أعرف مظلوما تواطأ الناس علي هضمه ولا زهدوا في إنصافه كالحقيقة.محمد الغزالي "No victim has ever been more repressed and alienated than the truth" Emad Soliman Nawfal Indiana University, Bloomington ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor