On 05/18/2016 09:53 PM, DFS wrote:
On 5/18/2016 10:58 PM, Larry Hudson wrote:
[snip...]
Why two loops?  Put both summations in a single loop.  Then you're only
scanning the alist once instead of twice.

groups1 = defaultdict(int)
groups2 = defaultdict(int)
for nm, matches, words in alist:
    groups1[nm] += matches
    groups2[nm] += words

     -=- Larry -=-


That gives me two lists - how do I combine them?

In the end that'll be at least 6 lines of code.  Do you have a one-liner to 
summarize the data?

Thanks

One-liner?  No way.  I did manage to get the whole conversion down to 6 lines...
(And I am far from an expert pythonista, a more experienced/expert programmer can probably do better.)

A two-line helper function
A two-line for loop
A one-line list comprehension
One line to declare a dictionary as an intermediate variable

#  A helper function -- adds two tuples
#  Could add square brackets to return a 2-element list instead of
#  a tuple, but the final result is the same either way.
def addtpl(t1, t2):
    return t1[0]+t2[0], t1[1]+t2[1]

#  Accumulate alist data into an intermediate temporary dictionary
tdic = {}
for dat in alist:
    tdic[dat[1]] = addtpl(tdic.get(dat[1], (0,0)), dat[2:])

#  Convert the dictionary back to a list of tuples
result = [(str(n), tdic[n][0], tdic[n][1]) for n in tdic]

Of course, this doesn't retain the original order, but you can use the sorted() function to sort the results by the names.

Here is the same thing as a single function that returns the sorted list...
(It also automatically throws away the temporary dictionary. But it's now 7 lines because of the added def line.)

def combine(lst):
    def addtpl(t1, t2):
        return [t1[0]+t2[0], t1[1]+t2[1]
    tdic = {}
    for dat in lst:
        tdic[dat[1]] = addtpl(tdic.get(dat[1], (0,0)), dat[2:])
    return sorted([(str(n), tdic[n][0], tdic[n][1]) for n in tdic])

     -=-Larry -=-

--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to