Home  >  Article  >  Backend Development  >  Some advanced features of python

Some advanced features of python

高洛峰
高洛峰Original
2017-02-15 14:45:29973browse

Preface

I have been using Python for almost half a year. I started to get in touch with it during the summer vacation last year. From the initial confusion to writing some small crawlers and finally getting started, many assignments can also be done using Python. Basically, Python is used. Abandoned C++. But I’m still a little too impatient. I can write some short codes, but I don’t know or have forgotten many features of python. I will go back to Liao Da’s tutorial to review it, and record the things that I think are more important.

Start

This article mainly records the content of the advanced features section of Liao Da’s tutorial, and writes down some of my understanding. In my opinion, these features are very pythonic, and they are very big when used in code~

List Comprehensions

I won’t talk about slicing and iteration, here I will directly Let’s take a look at list generation first. From the name, you can roughly guess that these are some methods of generating lists, such as: how to generate [1*1, 2*2, ...,10*10] ? You can use a loop to continuously add elements to the end of the list. If you use the pythonic method, that is, the list generation formula, it is:

>>> [x * x for x in range(1, 11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

It can also be followed by an if judgment, for example:

>>> [x * x for x in range(1, 11) if x%2==0]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

This way , originally it was necessary to use a loop to write 4 or 5 lines of code, but it was solved with one line, which is intuitive and clear.

You can also use two for loops to generate the full permutation:

>>> [m + n for m in 'ABC' for n in 'XYZ']
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']

How to add if judgment in this way? You can add it after each for statement, or add it at the end:

>>> [m + n for m in 'ABC' if m < &#39;C&#39; for n in &#39;XYZ&#39; if n < &#39;Z&#39;]
[&#39;AX&#39;, &#39;AY&#39;, &#39;BX&#39;, &#39;BY&#39;]
>>> [m + n for m in 'ABC' for n in 'XYZ' if n < &#39;Z&#39; and m < &#39;C&#39;]
[&#39;AX&#39;, &#39;AY&#39;, &#39;BX&#39;, &#39;BY&#39;]

You can also iterate multiple variables in a for statement at the same time. For example, dict's items() can iterate key and value at the same time:

>>> d = {'x': 'A', 'y': 'B', 'z': 'C' }
>>> [k + '=' + v for k, v in d.items()]
['y=B', 'x=A', 'z=C']

That’s almost it~

But I always wrote C++ in the past. This kind of thinking mode is difficult to change. I can only slowly become familiar with this syntax in use. Once I get used to it, I can subconsciously Written out.

Generator

Why use a generator? Liao Da's tutorial explains it in detail, but here's a brief summary:

  1. Because the contents of the list are placed in memory and are subject to memory restrictions, the capacity of the list is limited.

  2. If we only access very few elements, there is a huge waste of space.

  3. The generator can calculate the next value while iterating. In theory, the process can continue indefinitely and will not occupy a lot of memory.

Here is just a brief introduction, please Google for more details~

How to create a generator? The first method is similar to the list generation mentioned earlier. You only need to change [] to ():

>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x1022ef630>

As you can see, the method is roughly the same. What [] gets is an already obtained A list of all values, () gets a generator, which can be iterated using a for loop, but the generator cannot be accessed using subscripts, and can only be iterated once. If it is iterated again, a StopIteration exception will occur:

>>> for i in g:
...     print(i)
...
0
1
4
9
16
25
36
49
64
81
>>> for i in g:
...     print(i)
...
>>> next(g)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

But when we create a generator, next() will basically never be called, but it will be iterated through a for loop, and there is no need to care about StopIteration errors.

If the calculation algorithm is more complex and cannot be implemented using a for loop similar to list generation, you can also use a function to implement it. For example, the famous Fibonacci sequence:

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1
    return &#39;done&#39;

Regarding the yield keyword, I struggled with it for a long time when I first learned Python. I didn’t understand it until I saw the generator. You can roughly understand it by searching. I think it is troublesome to talk about it, so I will only say a few words. I am afraid of saying the wrong sentence. Liao Da's tutorial says this:

Functions are executed sequentially and return when encountering a return statement or the last line of function statements. The function that becomes a generator is executed every time next() is called, returns when encountering a yield statement, and continues execution from the yield statement returned last time when executed again.

It may be a little difficult to understand, but once you understand it, it’s easy to explain.

Of course, you can also add return to the function. In a generator function, if there is no return, it will execute until the function is completed by default. If it returns during execution, StopIteration will be thrown directly to terminate the iteration.

For example, in the above example, we found that the string of characters 'done' did not appear during the iteration, because the return value was treated as an Exception Value. If you want to display it, you can do this:

>>> g = fib(6)
>>> while True:
...     try:
...         x = next(g)
...         print('g:', x)
...     except StopIteration as e:
...         print('Generator return value:', e.value)
...         break
...
g: 1
g: 1
g: 2
g: 3
g: 5
g: 8
Generator return value: done

Iterator

Objects that can directly act on the for loop are called iterable objects. You can use the isinstance() function to determine whether it is an iterable object:

>>> from collections import Iterable
>>> isinstance([], Iterable)
True
>>> isinstance({}, Iterable)
True
>>> isinstance('abc', Iterable)
True
>>> isinstance((x for x in range(10)), Iterable)
True
>>> isinstance(100, Iterable)
False

The object that can be called by the next() function and continuously returns the next value is called an iterator: Iterator. Of course, you can still use isinstance() to determine whether an object is an Iterator object:

>>> from collections import Iterator
>>> isinstance((x for x in range(10)), Iterator)
True
>>> isinstance([], Iterator)
False
>>> isinstance({}, Iterator)
False
>>> isinstance('abc', Iterator)
False

Through the above two examples, it can be understood this way: the generator and list, tuple, str, etc. are all Iterable objects, and the generator simultaneously It is still an Iterator object, but list etc. are not. So can it be directly converted from Iterable objects to Iterator objects?

You can use the iter() function:

>>> isinstance(iter([]), Iterator)
True
>>> isinstance(iter('abc'), Iterator)
True

其实,Iterator 对象表示的是一个数据流,我们可以把这个数据流看做是一个有序序列,但却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以 Iterator 的计算是惰性的,只有在需要返回下一个数据时它才会计算。Iterator甚至可以表示一个无限大的数据流,但 list,tuple 什么的是不可能这样的。

更多关于 python 的一些高级特性相关文章请关注PHP中文网!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn