"You can't write comprehensions easily using Python."
I was told by a great person, so I went to various sites and studied. (Prerequisite knowledge is "Well, it's not just list comprehension !?" level)
Wikipedia-Intensions and Extensions
extension_li = []
for x in range(10):
extension_li.append(x**2)
extension_li
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Defined in []. Returns a list.
comprehension_li = [x**2 for x in range(10)]
comprehension_li
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Defined with {}.
comprehension_set = {i/2 for i in range(1,11)}
comprehension_set
{0.5, 1.0, 2.0, 2.5, 1.5, 3.0, 3.5, 4.0, 4.5, 5.0}
abb = ("NY","TX","MA","WA","CT")
state = ("New York", "Texas", "Massachusetts", "Washington", "Connecticut")
comprehension_dict = {i:j for i,j in zip(abb,state)}
comprehension_dict
{'WA': 'Washington',
'TX': 'Texas',
'NY': 'New York',
'MA': 'Massachusetts',
'CT': 'Connecticut'}
Defined in (). It is never a tuple comprehension, and what is returned is a generator that generates elements. Memory is saved because not all elements are stored in memory like a list.
comprehension_gen = (i%3 for i in range(1,10))
comprehension_gen
<generator object <genexpr> at 0x014CD900>
for i in comprehension_gen:print(i)
1
2
0
1
2
0
1
2
0
extension = [i for i in range(1,10) if i%2==0]
extension
[2, 4, 6, 8]
comprehension = [i if i%2==0 else 0 for i in range(1,10)]
comprehension
[0, 2, 0, 4, 0, 6, 0, 8, 0]
When else is entered, the conditional notation comes first. The reason is clear: "simply if statement" is a normal comprehension grammar, while "if ~ else statement" is treated as a ternary operator.
By the way, the python ternary operator is
** "(Value when condition is True) if (Condition) else (Value when condition is False)" **
It becomes the description. (Be careful because it is different from Java, C language, etc.)
I'm sorry for the worn-out material, but FizzBuzz can be easily written in one liner by using the if ~ else statement.
print(["FizzBuzz" if n % 15 == 0 else "Fizz" if n % 3 == 0 else "Buzz" if n % 5 == 0 else n for n in range(1,101)])
Or you can write like this.
print([(i%3==0 and 1 or 0)*"Fizz"+(i%5==0 and 1 or 0)*"Buzz" or i for i in range(1, 101)])
print([(i%3==0)*"Fizz"+(i%5==0)*"Buzz" or i for i in range(1, 101)])
[1, 2, 'Fizz', 4, 'Buzz', 'Fizz', 7, 8, 'Fizz', 'Buzz', 11, 'Fizz', 13, 14, 'FizzBuzz', 16, 17, 'Fizz', 19, 'Buzz', 'Fizz', 22, 23, 'Fizz', 'Buzz', 26, 'Fizz', 28, 29, 'FizzBuzz', 31, 32, 'Fizz', 34, 'Buzz', 'Fizz', 37, 38, 'Fizz', 'Buzz', 41, 'Fizz', 43, 44, 'FizzBuzz', 46, 47, 'Fizz', 49, 'Buzz', 'Fizz', 52, 53, 'Fizz', 'Buzz', 56, 'Fizz', 58, 59, 'FizzBuzz', 61, 62, 'Fizz', 64, 'Buzz', 'Fizz', 67, 68, 'Fizz', 'Buzz', 71, 'Fizz', 73, 74, 'FizzBuzz', 76, 77, 'Fizz', 79, 'Buzz', 'Fizz', 82, 83, 'Fizz', 'Buzz', 86, 'Fizz', 88, 89, 'FizzBuzz', 91, 92, 'Fizz', 94, 'Buzz', 'Fizz', 97, 98, 'Fizz', 'Buzz']
I can answer.
Here, as an example, we will compare the operations to create a list of squared values of [1,2,3,4,5,6,7,8,9,10].
%%timeit
list(map(lambda i : i**2, range(1,11)))
10000 loops, best of 3: 23.8 µs per loop
%%timeit
[i**2 for i in range(1,11)]
100000 loops, best of 3: 15.8 µs per loop
For filter, compare the operations of removing even numbers from [1,2,3,4,5,6,7,8,9,10].
%%timeit
list(filter(lambda i : i%2==0, range(1,11)))
10000 loops, best of 3: 19.3 µs per loop
%%timeit
[i for i in range(1,11) if i%2==0]
100000 loops, best of 3: 10.2 µs per loop
As you can see, the speed is different. Readability is also higher in the comprehension (in the sense that you can easily understand what you are doing) (individual differences).
Since we talked about processing speed, incidentally. What happens when you compare the speeds of the first list comprehension notation and normal list generation?
def for_loop(n):
extension = []
for x in range(n):
extension.append(x**2)
return extension
def comprehension(n):
return [x**2 for x in range(n)]
%timeit for_loop(1000)
1000 loops, best of 3: 1.58 ms per loop
%timeit comprehension(1000)
1000 loops, best of 3: 1.16 ms per loop
It's hard to notice the difference with my low-speed PC, but the difference is still clear. The reason is simply that the former takes time to retrieve the append attribute every time the for statement is turned. The thing is a trial, and only the reference of the append attribute is put out of the for statement and the time is measured.
def for_loop2(n):
extension = []
app = extension.append
for x in range(n):
app(x**2)
return extension
%timeit for_loop2(1000)
>>>1000 loops, best of 3: 1.27 ms per loop
As expected, the processing time was in the order of for_loop> for_loop2> comprehension. The difference between for_loop2 and comprehension probably means the speed of append itself.
Somehow, I understood how to handle the inclusion notation.
With this, I can't go to Python Master ... from today ...
Or rather, I thought it was a writing style peculiar to this comprehension python, but it seems to be used normally in many other functional languages.
I will post the sites that I used as a reference including them.
DSAS Developer's Room-Why Python's comprehensions are so fast?
Qiita --Detailed python comprehension
stackoverflow - if else in a list comprehension
Disease leading to knowledge-classify when using if ~ else in Python comprehension
Life with Python-Summary of how to use Python comprehensions
Recommended Posts