5 Wrong Use Cases Of Python List Comprehensions | by Anupam Chugh | Towards Data Science

List comprehensions are unarguably the most powerful feature of Python. They are pythonic, powerful, and provide readability.
But that easily opens up the door for misusing them. Or rather abusing in various forms. In doing so, your code only gets non-pythonic and hard to decipher by peers.
In the following section, we’ll look at a few incorrect ways of using Python list comprehensions with their replacements.
A lot of programmers when starting out with Python, begin using list comprehensions where it isn’t really needed.
For instance, in the following examples, using list comprehensions isn’t the best idea as we aren’t doing anything with the list.
vehicles = [ car, bike, truck ][ v.setLights(true) for v in vehicles ]names = [ "A", "B", "C" ][ print(i) for n in names ]
In such cases, it’s better to use the classic for loops as it’ll prevent the creation of an unnecessary list. List comprehensions aren’t meant to specify commands or set states on the elements.
You might want to transform characters of a string or simply add a bunch of numbers. In either of the cases, picking list comprehensions just because it’s fancy doesn’t mean it’s pythonic too.
Let’s consider the following example:
total = 0listOne = [1,2,3][total := total + x for x in listOne]
While the Python 3.8 assignment operator := lets us do a sum of list elements using list comprehensions, why reinvent a wheel when Python provides a built-in sum() function? The above list comprehension can be done away with a remarkably short piece of code:
sum(listOne)
Similarly, when you’re only splitting a string into characters(or transforming them), using list comprehension is overkill and not necessary at all:
str = "Fred"chars = [x for x in str]#use this instead:chars = list(str)
List comprehensions however good they are can become a pain when they’re nested. Readability issues are only further aggravated when the logic is lengthy.
Python list comprehensions should best be reserved for concise logic in order to adhere to pythonic code. This means it’s okay to let go of nested list comprehensions in favor of nested loops if need be.
The following example only showcases, how nested loops can be easier to comprehend and at times are a good substitute for long nested comprehensions.
list = [[1,2,3],[-1,-5,6]]flatten = [item           for sublist in list           for item in sublist           if item > 0]#using loopsflatten1 = []for rows in list:    for sublist in rows:        if sublist > 0:           flatten1.append(sublist)
List comprehensions let you create lists easily but they occupy memory for the whole time. This makes them very inefficient especially when dealing with large datasets.
Consider the below example where you’d easily run into out of memory errors.
sum([i * i for i in range(1000)])
Using a generator expression instead is recommended as it yields value one at a time:
sum(i* i for i in range(1000))
Another example where storing the list in memory is a bad idea is when you’re only looking for a single element based on a certain condition. The following list comprehension one-liner is inefficient.
first = [x for x in list          if x.get("id")=="12"]
We can substitute this with not only a generator expression but also set the next function in order to return when the first element matches a given condition:
first = next((x for x in list if x.get("id")=="12"), None)
Using itertools functions alongwith generator expression are an effective way to exit rather than using list comprehension which doesn’t support break or continue.
Again, you’ll be surprised to know how easy to get bogged down with list comprehensions and use it for unzipping tuples.
The below example just reinstates another incorrect use case where we’re splitting the tuple values into nested lists:
myList = [('A', 1), ('B', 2), ('C', 3)]result = [[ i for i, j in myList ],       [ j for i, j in myList ]]
Python already provides us with a specific built-in tool that lets us unzip tuples. Simply use the unpacking operator * to destructure the tuple and pass it to the zip function for creating separate lists.
result = list(zip(*myList))# [['A', 'B', 'C'], [1, 2, 3]]
Python List Comprehensions are powerful but they can be easily overused thereby making the code non-pythonic.
I hope the above incorrect approaches help you make a better judgment of when not to use list comprehensions.
That’s it for this one. Thanks for reading.