Re: [Tutor] adding dictionary values

2009-03-21 Thread عماد نوفل
2009/3/20 Kent Johnson ken...@tds.net

 2009/3/20 Emad Nawfal (عماد نوفل) emadnaw...@gmail.com:

  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


[Tutor] adding dictionary values

2009-03-20 Thread عماد نوفل
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


Re: [Tutor] adding dictionary values

2009-03-20 Thread 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 sasb ] + \
   [(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-03-20 Thread Kent Johnson
2009/3/20 greg whittier g...@thewhittiers.com:

 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

2009-03-20 Thread Richard Lovely
2009/3/20 Chris Fuller cfuller...@thinkingplanet.net:
 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 sasb ] + \
   [(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-03-20 Thread Kent Johnson
2009/3/20 Emad Nawfal (عماد نوفل) emadnaw...@gmail.com:

 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