From: Sion Arrowsmith on
Mark Lawrence <breamoreboy(a)yahoo.co.uk> wrote:
>On 22/06/2010 15:06, Neil Webster wrote:
>> I have a list of lists such as [[a,2,3,4],[b,10,11,12], [a,2,3,4]]. I
>> need to combine the two lists that have the same first character in
>> this example 'a'. In reality there are 656 lists within the list.
>> [ ... ]
>My simplistic approach.
>
>Sort the list (this happens in place).
>Use the itertools groupby function to place everything together, see
>http://docs.python.org/library/itertools.html?highlight=groupby#itertools.groupby
>Combine the lists in the groups.

I suspect the following is a more efficient way of acheiving the grouping:

d = collections.defaultdict(list)
for a in L:
d[a[0]].append(a[1:])

--
\S

under construction

From: Bruno Desthuilliers on
Neil Webster a �crit :
> Thanks for the help so far.
>
> The background to the problem is that the lists come from reading a
> dbf file. The code that I am trying to write is to merge lines of the
> dbf based on the first column. So in my example there would be three
> lines:
> a 2 3 4
> b 10 11 12
> a 2 3 4
>
> The expected output from the above example lines would be:
> a 4 6 8
> b 10 11 12
>
> ... and the lines are read as: [[a,2,3,4],[b,10,11,12], [a,2,3,4]]
>

If you don't care about the original ordering, the following code should
do.

# 8<----------------------------------------------------------------

def merge_rows(rows):
merged = dict()
for row in rows:
key, values = row[0], row[1:]
sums = merged.setdefault(key, [0, 0, 0])
for i, v in enumerate(values):
sums[i] += v

return [key] + value for key, value in merged.iteritems()]

import sys
def print_rows(rows, out=sys.stdout):
for row in rows:
print " ".join(map(str, row))

if __name__ == '__main__':
inputs = [['a',2,3,4],['b',10,11,12], ['a',2,3,4]]
expected = [['a',4,6,8],['b',10,11,12]]
print "inputs : "
print_rows(inputs)

outputs = merge_rows(inputs)
outputs.sort() # so we can do a simple equality test
assert outputs == expected, "Expected %s, got %s" % (
expected, outputs
)

print "outputs :"
print_rows(outputs)

# 8<----------------------------------------------------------------


> In response to not posting working code or actual inputs, ummm, that's
> why I am asking the question here.

In this context, "working code" means "minimal code that a) can be
executed and b) exhibits the problem you have, whatever the problem is".
This code should include or be shipped with example input data and
corresponding expected output data - as I did in the above code.


HTH