Let's say I want to create a list of ints
using Python that consists of the cubes of the numbers 1 through 10 only if the cube is evenly divisible by four.
I wrote this working line:
cube4 = [x ** 3 for x in range(1, 11) if (x ** 3) % 4 == 0]
My beef with this line of code is that it's computing the cube of x twice. Is there more pythonic way to write this line? Or is this as good as it'll get in a list comprehension?
Edit - My question is intended to be focused how to avoid extraneous calculation using the features and nuances of Python while still keeping code concise and readable. Though this solution could have probably been reached looking at other questions, I wanted to be sure that I knew the best answer to this question, not just a solution that works.
5. Using list comprehension. The method of list comprehension can be used to copy all the elements individually from one list to another. This takes around 0.217 seconds to complete.
>> 8.20 seconds As we can see, the for loop is slower than the list comprehension (9.9 seconds vs. 8.2 seconds). List comprehensions are faster than for loops to create lists. But, this is because we are creating a list by appending new elements to it at each iteration.
It's a simple operation, it's just creating a list of the squares of numbers from 1 to 50000. From the timed cells below, you can see that the list comprehension runs almost twice as fast as the for loop for this calculation. This is one of the primary benefits of using list comprehension.
You can use a generator expression:
cubed = (x ** 3 for x in range(1, 11))
cube4 = [c for c in cubed if c % 4 == 0]
This still iterates over range()
only once, but now the x ** 3
expression is calculated just the once as the generator expression is iterated over. You can combine it into one line:
cube4 = [c for c in (x ** 3 for x in range(1, 11)) if c % 4 == 0]
but keeping the generator expression on a separate line may aid in comprehension (no pun intended).
Demo:
>>> [c for c in (x ** 3 for x in range(1, 11)) if c % 4 == 0]
[8, 64, 216, 512, 1000]
Of course, mathematically speaking, for your simple example you could just use [x ** 3 for x in range(2, 11, 2)]
, but I suspect that wasn't quite the aim of your question. :-)
A number's cube is divisible by 4 if and only if the number is even. This is easy to see if you expand each number into its prime factors. Therefore:
cube4 = [x ** 3 for x in range(1, 11) if x % 2 == 0]
I love one-liners, but it's worth noting that there's another Pythonic way to produce the desired list
.
cube4 = []
for x in range(1, 11):
y = x ** 3
if not y%4:
cube4.append(y)
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