I have 3 lists-of-lists.
The sub-lists' field 1 is a name, field 2 is a number, and field 3 is a number. This format is always the same, and doesn't change. There are always the same names in the 3 lists; however, the order may not be the same.
a = [['jane', '1', '120'], ['bob', '3', '35'], ['joe', '5', '70']]
b = [['bob', '1', '12'], ['jane', '2', '240'], ['joe', '1', '100']]
c = [['joe', '2', '30'], ['jane', '5', '45'], ['bob', '0', '0']]
I would like a result (any object type) with the sum of fields 2 & 3 of the lists' sub-lists.
result = [['jane', '8', '405'], ['bob', '4', '47'], ['joe', '8', '200']]
In pseudo Python3 code, I'm guessing it'd look like this, but I cannot figure out the correct way to do it in Python3. Let alone doing it in a Pythonic way:
def sum_f2_f3(list_a, list_b)
where element[0] in list_a.sub_list == element[0] in list_b.sub_list:
x = element[0]
result[x:1] = list_a.sub_list[0:1] + list_b.sub_list[0:1]
result[x:2] = list_a.sub_list[0:2] + list_b.sub_list[0:2]
return result
result = sum_f2_f3(sum_f2_f3(a,b), c)
Any ideas? What built-in Python tools can help me with this?
To illustrate why using the right data structures makes things a lot easier…
Let's say that a
, b
, and c
were actually dict
s, and your numbers were actually int
s instead of str
s. After all, the whole point of a dict
is to look things up by name, and the whole point of an int
is to be able to do arithmetic. So:
a = {'jane': [1, 120], 'bob': [3, 35], 'joe': [5, 70]}
b = {'bob': [1, 12], 'jane': [2, 240], 'joe': [1, 100]}
c = {'joe': [2, 30], 'jane': [5, 45], 'bob': [0, 0]}
Now, all you have to do is this:
result = {}
for d in a, b, c:
for k, v in d.items():
if not k in result:
result[k] = [0, 0]
result[k][0] += v[0]
result[k][1] += v[1]
And the result is:
{'bob': [4, 47], 'jane': [8, 405], 'joe': [8, 200]}
There's still a bit of room for improvement—you can use a defaultdict
to get rid of the if not k in result:
bit—but even with just novice-level stuff this is pretty compact and simple.
But what if you got those lists as input—you'd like to have nice dicts in the end, but you don't start there?
You can write a function to convert them, like this:
def convert(list_of_lists):
result = {}
for element in list_of_lists:
key = element[0]
values = []
for value in element[1:]:
values.append(int(value))
result[key] = values
return result
And if you spot the familiar values = []… for value in … values.append(…)
pattern, you can turn that into the simple list comprehension [int(value) for value in element[1:]]
. And then the whole thing is the dict equivalent of the same pattern, so you can reduce all of it to:
return {element[0]: [int(value) for value in element[1:]] for element in list_of_lists}
Meanwhile, if you need to convert back to the original form, that's just:
def unconvert(dict_of_lists):
result = []
for key, values in dict_of_lists.items():
element = [key] + [str(value) for value in values]
result.append(element)
return result
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With