How did they do all that in one line? A Codewars challenge explanation
Tags: beginners
Published: 2019-08-06 13:27:49

Today I worked on a challenge on Codewars and saw a very concise solution submitted by another user on the site. I'll first just show the code, then explain what's going on.

```
def up_array(arr):
  if not arr or min(arr) < 0 or max(arr) > 9:
    return None
  else:
    return [int(y) for y in str(int("".join([str(x) for x in arr])) + 1)]
```

The challenge can be found [here](https://www.codewars.com/kata/plus-1-array/python), but the basic idea is to take a list of integers, add one to the value represented by that list, and return a new list with that new value.


Let's break down that solution.    
First, there's an if statement with multiple parts. `if` starts it off. Then there is the expression `not arr`. This is nice. It takes advantage of the fact that data types like list can have a boolean interpretation. In this case, if the array is empty, `not arr` will evaluate to `True` (because `arr` would evaluate to `False`).  
This is attached to the next bit by `or`. The next two parts are more straightforward. If the minimum of the array is less than zero or if the maximum of the array is greater than nine, the if statement will evaluate to `True`.  
So, if the list is empty or contains elements out of range, the function will return `None`.

Now the real meat of it.  
`return [int(y) for y in str(int("".join([str(x) for x in arr])) + 1)]`
Wheh! That's a mouthful.  
At the center of the parenthesis and brackets, we have: `str(x) for x in arr`. That seems straightforward enough. It seems like this would be functionally equivalent to the following (which is pseudo code):
```
y = []
for x in arr:
    y = str(x)
```

The point is, I think that `str(x) for x in arr` would return an array of strings which have been converted from the integers in arr.  
Let's test this.  
```
In      arr = [2,3,9]

In      [str(x) for x in arr]
Out     ['2', '3', '9']
```
Yes. That's how it works.

Next step: `"".join([str(x) for x in arr])`. It looks like we are joining an empty string to the array of strings. Or maybe we are joining the array of strings into one array with the empty string between them. I can test this.
```
In[4]:     [str(x) for x in arr]
Out[4]:    ['2', '3', '9']

In[5]:     "".join([str(x) for x in arr])
Out[5]:    '239'


In[6]      "-".join([str(x) for x in arr])
Out[6]:    '2-3-9'
```
Yes. It joins together the strings of the array, with either nothing ("") or a dash ("-") between the strings.

What next?
We have `(int("".join([str(x) for x in arr])) + 1)`. This is pretty straight forward. Take the result from above, convert it to an integer, then add one. Cool.

Next, we have `str(int("".join([str(x) for x in arr])) + 1)`. This is an easy step. We're just taking the resulting integer and converting it to a string.

This next bit is a bit more tricky. `[int(y) for y in str(int("".join([str(x) for x in arr])) + 1)]`. I believe this does something analogous to:
```
new_list = []
for y in my_string:
    y = int(y)
    new_list.append(y)
```
So it should take each character from the string, convert that to an integer, and put it into a list. Let's test it.
```
In[7]:    [int(y) for y in str(int("".join([str(x) for x in arr])) + 1)]
Out[7]:   [2, 4, 0]
```
Yes. that's what it does. Good.

Then there's just one more step: `return [int(y) for y in str(int("".join([str(x) for x in arr])) + 1)]`. That means take the result of all that code, and return it as the function output.

## Summary
So, to summarize that code, we have:
```
def up_array(arr):
  if not arr or min(arr) < 0 or max(arr) > 9:
    return None
  else:
    return [int(y) for y in str(int("".join([str(x) for x in arr])) + 1)]
```
Which, if I translate to pseudo code, would look something like:
```
define function up_array as a function of the array, arr:
    if there are problems with the input:
        return nothing
    otherwise:
        take a list of integers, convert each to a string and put them
        together into a string, convert that string to an int, add one to 
        that int, and convert that result to a string. Then pull out the 
        characters of that string one by one, converting each into a 
        string and populating a list with those strings.
        Return that list.
```

I learned a lot from picking this apart, and I hope you learned something from reading it.