Old Dog’s New Tricks – List Comprehension in Python
If you were trying to come up with a list of iconic programming idioms, “For Loops” would probably make the cut. For someone like me that learned about loops via COBOL’s crazy “Perform” loop syntax – changing paradigms (yet again) can sometimes prove difficult.
I was attracted to Python initially because it is different. So I have done my best to leave my preconceived notions about writing code behind as I embraced the challenge of becoming an effective Python coder.
List Comprehension proved to be a concept that I had to invest more time into studying than other Pythonic approaches.
What is List Comprehension in Python?
List Comprehension basically creates lists based on existing lists. Sounds exciting, no? The magical part is that you can manipulate lists in an (almost) infinite number of ways.
This eliminates the need for in-efficient nested for-loops as well as (in Python) the need for (most) Lambda functions. Which means that there is very little need for reduce(), filter() and map() as well…
A list comprehension typically has 3 parts:
- Output – list of strings, numbers, lists, objects, etc.
- For Statements
- Conditional Filtering (optional)
And the code will have a pattern like this pseudocode:
i for i if()
[[i (output_value) ] for i (in iterable) if (filter conditions)]
I’ll give you some real Python code to look at lol, but the above helped me visualize the concept of list comprehension in Python initially.
Consider this old school for loop:
my_list = [1,2,3,4,5] new_list =  for i in my_list: new_list.append(i**2) new_list # [1, 4, 9, 16, 25]
Where each item in the list is raised to the power of 2 in a for loop. A much more Pythonic way of accomplishing this is :
# also squares each number in my_list and appends the result new_list new_list = [i**2 for i in my_list] # [1, 4, 9, 16, 25]
Admittedly these are very simple examples, however they give a clue as to how I came to understand list comprehension in Python.
If, like me, you come from a tradition of old school for-loops – go ahead and write out the for loop first and then figure out how to write in as a comprehension. In my experience you won’t have to do this for very long before you get the hang of it.
The above example has the output (i**2) and the iterable(my_list). It leaves out optional filtering:
filtered_list = [i**2 for i in my_list if i%2 == 0] #[4, 16]
Same as new_list but filtered so that it only contains even numbers after they’ve been squared.
You can also create comprehensions that use if/else:
# squares each number in a list if even, else cubes it [i**2 if i%2 == 0 else i**3 for i in my_list] #[1, 4, 27, 16, 125]
Note that while this seems a little different it follows the same pattern:
The (i**2 if i%2 == 0 else i**3) is all the first i in the [i for i in list] structure if you will.
That’s the simple explanation of list comprehension in Python, but far from the end of the story.
I will be discussing some more advanced ideas with list comprehensions on Friday, but until then you can get all the code I created for study on list comprehension in a Jupyter Notebook here.