📜 ⬆️ ⬇️

Python unknown

On Habré already there are several articles \ translations that tell about the unknown features \ subtleties \ features of Python. I will try not to repeat them, but to supplement them, but if it so happens that you have already seen it somewhere, do not be upset. I am sure that there is something interesting for you.

So let's go.

Chaining comparison operators:

>>> 1 < 5 < 10 True >>> 1 < 11 < 10 False >>> 1 < 11 > 10 True 

It is also true that all the magic will break if you add parentheses:

 >>> (1 < 11) > 10 False 

Doka
')
iter and two parameters

The built-in function of iter returns an iterator for the passed sequence. But, if two parameters are passed, the first should be a callable object, and the second should be the result of calling the first object, at which the iteration should be stopped. For example, we read from the file before the first empty line:
 with open('mydata.txt') as fp: for line in iter(fp.readline, ''): process_line(line) 

Doka

contextlib

Allows you to easily and beautifully use the syntax with EXPR as VAR for your own objects, functions, etc. Example from documentation:
 from contextlib import contextmanager @contextmanager def tag(name): print "[%s]" % name yield print "[/%s]" % name >>> with tag("h1"): ... print "foo" ... [h1] foo [/h1] 

Doc , PEP 343

Default Arguments

Here are a few hacks. First, using mutable objects as default arguments is almost always a bad idea:
 >>> def foo(a=list()): ... a.append(1) ... print a ... >>> foo() [1] >>> foo() [1, 1] >>> foo() [1, 1, 1] 

Why is that? The default argument values ​​are defined only once when the function is created and are stored in the func_defaults property:
 >>> foo.func_defaults ([1, 1, 1],) 


But there is in the appendage and a useful recipe. The following code does not quite work as expected:
 >>> l = [] >>> for i in range(3): ... l.append(lambda: i * 2) ... >>> for x in l: ... x() ... 4 4 4 

You can fix it simply and elegantly - just replace lambda: i * 2 with lambda i = i: i * 2 :
 >>> l = [] >>> for i in range(3): ... l.append(lambda i=i: i * 2) ... >>> for x in l: ... x() ... 0 2 4 

You can read about names and binding to them in the Execution Model .

Ellipsis

Depending on the context ... (three dots) may be a valid syntax. Thus, the list [...] passes to the __getitem__ function an object of the Ellipsis type - the only and unique one of its kind. Demonstration:
 >>> class L(list): ... def __getitem__(self, *args): ... print args ... return list.__getitem__(self, *args) ... >>> l[...] (Ellipsis,) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 4, in __getitem__ TypeError: list indices must be integers, not ellipsis 

This charm is used in Numpy .

Exchange of variable values

In the 10th grade, we were offered a computer science lesson at the computer lesson — swapping the values ​​of two variables without using the third one. In Python, this is not even a question:
 >>> a = 10 >>> b = 5 >>> a, b (10, 5) >>> a, b = b, a >>> a, b (5, 10) 


Nested list comprehensions

You can use multiple for list comprehensions in:
 >>> l = [[1,2,3], [4,5,6]] >>> [lll * 2 for ll in l for lll in ll] [2, 4, 6, 8, 10, 12] 


Creating multiple editable objects

For example, you need to create a list of 5 lists. I want to do this:
 >>> l = [[]] * 5 >>> l [[], [], [], [], []] 

But you can not:
 >>> l[0].append(1) >>> l [[1], [1], [1], [1], [1]] 

Better probably like this:
 >>> l = [[] for _ in range(5)] 


rot13, string_escape, unicode_escape encoding

Rot13's super secret encryption method :
 >>> 'Hello world!'.encode('rot13') 'Uryyb jbeyq!' >>> 'Uryyb jbeyq!'.decode('rot13') u'Hello world!' 

Further. For example, there is a string from an external source, while in the string there are literals \ n, \ t, \ r , etc. How to get a formatted string (in fact, to make a safe eval )?
 >>> s = 'Hello\\n\\rworld!' >>> s 'Hello\\n\\rworld!' >>> repr(s) "'Hello\\\\n\\\\rworld!'" >>> print s.decode('string_escape') Hello world! 

unicode_escape works in the same way, only with Unicode, not with strings. He also knows how to turn the string '\ u0457' into the letter "ї":
 >>> print '\u0457'.decode('unicode_escape') ї 

The list of supported encodings is standard-encodings .

textwrap

Very useful for working with texts. We make many small ones from a long line:
 >>> s = "Python is a programming language that lets you work more quickly and integrate your systems more effectively. You can learn to use Python and see almost immediate gains in productivity and lower maintenance costs." >>> print textwrap.fill(s, 25) Python is a programming language that lets you work more quickly and integrate your systems more effectively. You can learn to use Python and see almost immediate gains in productivity and lower maintenance costs. 

Doc - there is still a lot of tasty.

itertools

Full of emotion. Read-do not read, especially the section with recipes. Here I will remember the grouper :
 >>> def grouper(n, iterable, fillvalue=None): ... "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx" ... args = [iter(iterable)] * n ... return izip_longest(fillvalue=fillvalue, *args) ... >>> list(grouper(2, [1,2,3,4,5,6])) [(1, 2), (3, 4), (5, 6)] >>> list(grouper(3, [1,2,3,4,5,6])) [(1, 2, 3), (4, 5, 6)] >>> list(grouper(4, [1,2,3,4,5,6], fillvalue=0)) [(1, 2, 3, 4), (5, 6, 0, 0)] 

the trick is that we work with one iterator

Conclusions


Most of the information from the wonderful topic on StackOverFlow , the rest is our own observations. You can write a lot on this topic, so I tried to share only the most interesting and useful.
Thanks for attention!
May the power of documentation come with you!

PS If there are comments - I will be very grateful for the messages in a personal.

Source: https://habr.com/ru/post/123821/


All Articles