The other day, when I was looking at the trend of articles on Qiita, I saw something called "walrus operator". The walrus operator itself is a new grammar for Python, but I didn't really follow the latest specs myself. In the past, I wrote an article "Maybe I don't know the world of Python minor grammar", but I want to update my knowledge soon. So I decided to follow the recently added grammar. If you just touch the programming language, you can usually do something if you remember for, if, function definition, class definition, but if you want to write it short and neatly, it is very effective to use a dedicated syntax. For me, I like Python because it's an excellent choice. I won't introduce everything here, but it seems to be easy for me to use. I will pick up only what I think.
PEP 448 extends the use of the * iterable unpacking operator and the ** dictionary unpacking operator. Can now be used with any number of unpacking in function calls:
Hey. I thought. For example, in Python 2.7 series, the behavior is as follows.
>>> def f(a,b,c,d):
... return 1
...
>>> f(*[0,1,2,3])
1
>>> f(*[0,1],*[2,3])
File "<stdin>", line 1
f(*[0,1],*[2,3])
^
SyntaxError: invalid syntax
When calling a function while unpacking a list using *
in this way, only one list could be specified. However, since Python 3.5, more than one works.
>>> def f(a,b,c,d):
... return 1
...
>>> f(*[0,1,2,3])
1
>>> f(*[0,1],*[2,3])
1
Oh. The official Python documentation also includes examples of tuples and dictionaries, such as:
>>> {*range(4), 4, *(5, 6, 7)}
{0, 1, 2, 3, 4, 5, 6, 7}
>>> {'x': 1, **{'y': 2}}
{'x': 1, 'y': 2}
What's a little interesting is that you can also create a generator like range (4)
.
Introduced: Python3.5
Formatted string literals are similar to the formatted string by str.format () with a'f' prefix. These have replacement fields enclosed in curly braces. Substitution fields are expressions that are evaluated at run time and are formatted by the format () protocol:
>>> name = "Fred"
>>> f"He said his name is {name}."
'He said his name is Fred.'
This is usually a handy guy. If it is a character string with f
at the beginning, it will expand the character string just by writing it in the format of{name}
. This used to be a short hand
name = "Fred"
"He said his name is {name}.".format(**locals())
I was able to write something like this, but if it's such an annoying way of writing, %
is fine. I didn't use it. However, with the introduction of the f character string, the number of keystrokes is overwhelmingly smaller.
The Python formula also covered a complex example of nesting the {}
part.
>>> width = 10
>>> precision = 4
>>> value = decimal.Decimal("12.34567")
>>> f"result: {value:{width}.{precision}}" # nested fields
'result: 12.35'
However, after a little trial, it doesn't re-expand after putting it in a variable.
>>> template = "{name}"
>>> f"{template}"
'{name}'
(Well, if you try to do that, it seems that Turing completeness will be achieved with just the f character string ...)
Introduction: Python3.6
PEP 515 allows you to use underscores in numeric literals for better readability.
>>> 1_000_000_000_000_000
1000000000000000
>>> 0x_FF_FF_FF_FF
4294967295
Well, I don't use it in business so much ... However, when I run around the loop in a numerical calculation system, it's hard to tell whether it's 100,000 or 1 million, so this is good.
Introduction: Python3.6
It's not a grammar, but I'll introduce it because it's very convenient for debugging.
break.py
i = 1
print(i)
breakpoint()
i += 1
print(i)
Suppose you write the code. When you do this,
$ python break.py
1
> /home/kotauchisunsun/work/python_practice/break.py(4)<module>()
-> i += 1
(Pdb) i
1
In that way, when you call breakpoint ()
, pdb will start running and you can check the contents of the variables.
It doesn't really matter if the IDE is built-in, but it can be useful if you just want to do it from the command line.
Introduced: Python 3.7
The property of preserving the insertion order of dict objects has been officially declared part of the Python language specification.
As I learned from the article Favorite new features of Python 3.7, ** dictionary types are now saved in order. ** Really?
For python2.7
$ python2.7
Python 2.7.17 (default, Nov 7 2019, 10:07:09)
[GCC 7.4.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> {"c":1,"b":2,"a":3}.keys()
['a', 'c', 'b']
>>> {"a":1,"b":2,"c":3}.keys()
['a', 'c', 'b']
For python3.8 series
$ python
Python 3.8.0 (default, Jun 27 2020, 00:43:29)
[GCC 7.5.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> {"c":1,"b":2,"a":3}.keys()
dict_keys(['c', 'b', 'a'])
>>> {"a":1,"b":2,"c":3}.keys()
dict_keys(['a', 'b', 'c'])
Previously, there was ʻOrderedDict` in collections as a class dedicated to it, but dict is in the order of insertion, isn't it? This is a good thing, but ** conversely, it seems that you will be addicted to the code written assuming Python 3.7 series when you bring it to Python 3.5 series. ** It seems better to keep this change in mind.
Introduced: Python 3.7
As part of the larger syntax, a new syntax: = has been added to assign values to variables. This syntax resembles a walrus eye and fangs, hence the nickname "walrus operator."
if (n := len(a)) > 10:
print(f"List is too long ({n} elements, expected <= 10)")
Hmmm this official example? I wasn't so happy, but the following example was good.
[clean_name.title() for name in names
if (clean_name := normalize('NFC', name)) in allowed_names]
This example is good. I thought that it was the old way of writing
normailze_name_list = map(x: normalize('NFC',x),names)
clean_name_list = filter(x: x in allowed_names, normalize_name_list)
[x.title() for x in clean_name_list]
There were a lot of redundant parts, such as how to write, but you can write it short and neatly. Occasionally, I wanted to bring in the result of the judgment as an if statement of the comprehension expression as an element, so this is quite nice.
Introduced: Python3.8
The = specifier has been enabled for formatted string literals (f-string). An f-string, such as f'{expr =}', is displayed in the order of the expression written in f-string, the equal sign, and the string representation of the evaluated expression.
user = 'eric_idle'
member_since = date(1975, 7, 31)
f'{user=} {member_since=}'
"user='eric_idle' member_since=datetime.date(1975, 7, 31)"
For me, I thought, "Why ...", but it seems that it was introduced. My personal negative opinion is that this works basically only for debugging, and it's a syntax that doesn't really go into production code, so hmm. I thought. Is there any other use? I went to see the original discussion, but it seems to be mainly for debugging.
https://bugs.python.org/issue36817
Introduced: Python3.8
When I look at a relatively new language, generics do not enter. Or, the null coalescing operator is. How about the Elvis operator? I hear stories like that, but Python doesn't listen to that kind of story. It was the impression that. Type Hinting is certainly a big story, but it's an optional story, and I didn't use async / await much personally, so I wasn't interested in it. Meanwhile, a strange thing called a walrus operator enters Python. I was a little intrigued, so I looked it up. I hope you know the grammar around here. I think that it is not included in the introductory book. Do you know such things as you go, or do you know in articles like this? That's a pretty difficult task. I think.
https://docs.python.org/ja/3.5/whatsnew/3.5.html https://docs.python.org/ja/3.6/whatsnew/3.6.html https://docs.python.org/ja/3.7/whatsnew/3.7.html https://docs.python.org/ja/3.8/whatsnew/3.8.html
Recommended Posts