How to Sum Elements of Two Lists in Python
Tags: python, beginners, programming, tutorial
Published: 2019-02-27 19:50:33

Welcome back to another edition of the How to Python series. This time I want to sum elements of two lists in Python. I got the inspiration for this topic while trying to do just this at work, so let’s see how it goes!

## Problem Introduction

Recently, I ran into a problem where a library wasn’t working exactly how I wanted, so I had to hack together the results to make my life a bit easier. In this scenario, I had a connection library which I was using to list all the available devices. However, the list functionality short circuited for certain types of connections, so it never actually listed everything. As a result, I was forced to run the function twice: once for USB and again for Ethernet.

The results of this list function returned a list that looked something like the following:

```python
# [size, [types], [interfaces], [serial numbers], [IP addresses]]
[2, [7, 7], [1, 2], [2314567, 8374163], [0, 84302738]]
```

However, I was stuck retrieving the lists separately:

```python
[1, [7], [2], [8374163], [84302738]]  # Ethernet
[1, [7], [1], [2314567], [0]]  # USB
```

Naturally, I wanted to be able to merge the two lists back into what I was expecting initially. However, I wasn’t totally sure how I was going to do that. So, let’s take a look at some possible solutions.

## Solutions

When it comes to merging two lists, there are several possible ways to do it. Here are just a few.

### Merge Two Lists by Hand

At first, we might try merging the two lists by hand. In other words, we might try the following:

```python
ethernet_devices = [1, [7], [2], [8374163], [84302738]]
usb_devices = [1, [7], [1], [2314567], [0]]
all_devices = [
    ethernet_devices[0] + usb_devices[0],
    ethernet_devices[1] + usb_devices[1],
    ethernet_devices[2] + usb_devices[2],
    ethernet_devices[3] + usb_devices[3],
    ethernet_devices[4] + usb_devices[4]
]
```

Now, that solution is hardly elegant, but it gets the job done. However, there has to be a better way. After all, we are already taking advantage of the fact that [lists can be merged using the same operator as addition][2]. Why not take advantage of this property in a loop?

### Sum Elements of Two Lists with a Comprehension

Just like the last lesson on [inverting dictionaries in Python][1], we can take advantage of comprehensions to dramatically simplify this problem. Let’s take a look:

```python
ethernet_devices = [1, [7], [2], [8374163], [84302738]]
usb_devices = [1, [7], [1], [2314567], [0]]
all_devices = [x + y for x, y in zip(ethernet_devices, usb_devices)]
```

Now we’re talking! That’s five lines of tedious mapping compressed down into a simple list comprehension. But wait, it gets better:

```python
all_devices = [sum(pair) for pair in zip(ethernet_devices, usb_devices)]
```

Or, does it? Thanks to our fried, [rhymes][4], we'll notice that this solution **doesn't actually work** for our situation. While it does a great job summing integers in an iterable, it crashes when trying to merge two sublists with the following error:

```shell
Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    all_devices = [sum(pair) for pair in zip(ethernet_devices, usb_devices)]
  File "<pyshell#3>", line 1, in <listcomp>
    all_devices = [sum(pair) for pair in zip(ethernet_devices, usb_devices)]
TypeError: unsupported operand type(s) for +: 'int' and 'list'
```

That said, you may find it useful for merging two lists of strictly integers.

### Sum Elements of Two Lists with a Mapping

At this point, we’ve basically answered our question. However, there is another solution which requires arguably even less code. Check it out:

```python
ethernet_devices = [1, [7], [2], [8374163], [84302738]]
usb_devices = [1, [7], [1], [2314567], [0]]
import operator
all_devices = list(map(operator.add, ethernet_devices, usb_devices))
```

Not totally certain of the performance impact here, but it sure is a pretty solution. Of course, we also need to add a dependency which does make this solution a bit less attractive. In fact, if we were going to go down that road, we could easily leverage numpy:

```python
ethernet_devices = [1, [7], [2], [8374163], [84302738]]
usb_devices = [1, [7], [1], [2314567], [0]]
import numpy as np
all_devices = np.add(ethernet_devices, usb_devices)
```

However, numpy is a massive library, so we should probably stick with our list comprehensions.

## A Little Recap

Using the handful of methods above, we should be able to sum elements of two lists.

```python
ethernet_devices = [1, [7], [2], [8374163], [84302738]]
usb_devices = [1, [7], [1], [2314567], [0]]

# The long way
all_devices = [
    ethernet_devices[0] + usb_devices[0],
    ethernet_devices[1] + usb_devices[1],
    ethernet_devices[2] + usb_devices[2],
    ethernet_devices[3] + usb_devices[3],
    ethernet_devices[4] + usb_devices[4]
]

# Some comprehension magic
all_devices = [x + y for x, y in zip(ethernet_devices, usb_devices)]

# Let's use maps
import operator 
all_devices = list(map(operator.add, ethernet_devices, usb_devices))

# We can't forget our favorite computation library
import numpy as np 
all_devices = np.add(ethernet_devices, usb_devices)
```

As we can see, there are a lot of ways to run an element-wise sum of two lists. Take your pick.

As always, thanks for stopping by! If you’re interested in learning more about Python, consider [subscribing to The Renegade Coder][3], so you’ll never miss another article. 

[1]: https://dev.to/renegadecoder94/how-to-invert-a-dictionary-in-python-2150
[2]: https://www.pythoncentral.io/how-to-merge-lists-in-python/
[3]: https://therenegadecoder.com/members/
[4]: https://dev.to/rhymes/comment/94i5