Re: [Tutor] adding dictionary values

2009-03-21 Thread عماد نوفل
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-03-20 Thread 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
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] adding dictionary values

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

2009-03-20 Thread Chris Fuller

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

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 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-03-20 Thread greg whittier
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

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