[PYTHON] This and that of the inclusion notation.

"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)

Intensional and intensional notation

Wikipedia-Intensions and Extensions

Python comprehension 4 patterns

1. List comprehension

Normal list generation

extension_li = []
for x in range(10):
    extension_li.append(x**2)
extension_li
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

List comprehension

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]

2. Set inclusion

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}

3. Dictionary inclusion

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'}

4. Generator type

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

if location

When simply including an if statement

extension = [i for i in range(1,10) if i%2==0]
extension
[2, 4, 6, 8]

If ~ else statement

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']

Can map or filter be used instead?

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).

Talk about speed

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.

at the end

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.

~ Reference ~

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

This and that of the inclusion notation.
This and that of python properties
Master the inclusion notation
matplotlib this and that
This and that about pd.DataFrame
This and that using reflect
Zabbix API this and that
The story of Python and the story of NaN
This and that learned from boost.python
This and that using NLTK (memo)
[Notes / Updated from time to time] This and that of Azure Functions
About Boxplot and Violinplot that visualize the variability of independent data
Verification of the theory that "Python and Swift are quite similar"
Memorandum of python beginners About inclusion notation
Review the concept and terminology of regression
The story of trying deep3d and losing
The advantages and disadvantages of Django that people with one year of experience think
[Python] The movement of the decorator that can be understood this time ② The decorator that receives the argument
About the behavior of copy, deepcopy and numpy.copy
About the X-axis notation of Matplotlib bar graphs
The story of creating (probably) the smallest skill that implements personalization and in-skill billing
Summary of the differences between PHP and Python
Full understanding of the concepts of Bellman-Ford and Dijkstra
Talking about the features that pandas and I were in charge of in the project
The answer of "1/2" is different between python2 and 3
zsh settings that facilitate the use of virtualenv
The story of making a box that interconnects Pepper's AL Memory and MQTT
Organize the meaning of methods, classes and objects
Specifying the range of ruby and python arrays
One liner that lists the colors of matplotlib
Change the color of Fabric errors and warnings
Compare the speed of Python append and map
This is the only basic review of Python ~ 1 ~
This is the only basic review of Python ~ 2 ~
[Python] A program that calculates the number of updates of the highest and lowest records
This is the only basic review of Python ~ 3 ~
General description of the CPUFreq core and CPUFreq notifiers
This and that useful when used with nohup
Organize the super-basic usage of Autotools and pkg-config
I read and implemented the Variants of UKR
About the * (asterisk) argument of python (and itertools.starmap)
A discussion of the strengths and weaknesses of Python
The nice and regrettable parts of Cloud Datalab
It seems that the module of train_test_split changes from 0.20, and Deprecation Warning appears at 0.18.
Consideration of the difference between ROC curve and PR curve
A story that reduces the effort of operation / maintenance
The story of Python without increment and decrement operators.
Automatically determine and process the encoding of the text file
relation of the Fibonacci number series and the Golden ratio
The process of installing Atom and getting Python running
Python --Explanation and usage summary of the top 24 packages
Make a BOT that shortens the URL of Discord
Visualize the range of interpolation and extrapolation with python
[FSL] Measurement of segment and volume of the basal ganglia
Think about the next generation of Rack and WSGI
# Function that returns the character code of a string
Referencing and changing the upper bound of Python recursion
I checked out the versions of Blender and Python
PHP and Python samples that hit the ChatWork API
Note that the latest link of ius has changed
I checked the default OS and shell of docker-machine