Python is great, it has many advanced usages worthy of careful consideration and learning to use. This article will summarize and introduce a set of advanced features of Python based on daily use, including: list comprehensions, iterators and generators, and decorators.
Scenario 1: Combine all the elements whose one-dimensional data is a in a three-dimensional list to form a new two-dimensional list.
The simplest method: create a new list, traverse the original three-dimensional list, and determine whether the one-dimensional data is a, if it is a, append the element to the new list.
Disadvantages: the code is too cumbersome, for Python, the execution speed will be much slower.
For scenario 1, we should first think of using list comprehension to solve the processing, and one line of code can be solved:
lista =[item for item in array if item[0]=='a']
So, what is a list comprehension?
Official explanation: List comprehension is a very simple but powerful built-in Python generative that can be used to create lists.
**How to be strong? **
As you can see, the use of list comprehensions is shorter. In addition, because it is a built-in usage of Python, the bottom layer is implemented in C language, which is faster than writing Python code.
Scenario 2: For a list, it is necessary to traverse both the index and the elements.
Here you can use the Python built-in function enumerate to better get the index in the loop.
array =['I','love','Python']for i, element inenumerate(array):
array[i]='%d: %s'%(i, seq[i])
It can be refactored using list comprehensions:
def getitem(index, element):return'%d: %s'%(index, element)
array =['I','love','Python']
arrayIndex =[getitem(index, element)for index, element inenumerate(array)]
It is said that this way of writing is more Pythonic.
Summary: If you want to do some processing on the existing iterable object, and then generate a new list, using the list comprehension will be the most convenient way.
The iteration here can refer to a for loop. In Python, for lists, dicts and files can be used, but they are not iterators, they are iterable objects.
What iterable object
The simplest explanation: the object that can be looped using the for...in... statement is an iterable object (Iterable), which can be judged by the isinstance() method.
from collections import Iterable
type =isinstance('python', Iterable)
print type
What is an iterator
An iterator refers to an object that can be called back using the next() method. You can use the iter() method on an iterable object to convert it into an iterator.
temp =iter([1,2,3])
print type(temp)
print next(temp)
At this point temp is an iterator. So, iterators are based on two methods:
It can be understood that the object that can be called by the next() function and continuously returns the next value is an iterator. When defining a decorator, you will need to define both methods.
Advantages of iterators
When building an iterator, instead of loading all the elements at once, the elements are returned when the next method is called, so there is no need to consider memory issues.
Iterator application scenarios
So, in what scenarios can iterators be used?
A generator is a high-level iterator that makes the code required for a function that needs to return a series of elements simpler and more efficient (not as verbose as creating iterator code).
Generator function
The generator function is based on the yield instruction, which can pause a function and return an intermediate result. When you need a function that will return a sequence or execute in a loop, you can use a generator, because when these elements are passed to another function for subsequent processing, returning one element at a time can effectively improve the overall performance.
A common application scenario is to use the stream data buffer of the generator.
Generator expression
A generative expression is a convenient way to implement a generator, replacing the square brackets in the list comprehension with parentheses.
The difference with the list comprehension: the list comprehension can directly create a table, but the generator expression is a calculation while looping, so that the elements of the list can be calculated one by one during the loop, without creating a complete list , Thereby saving a lot of space.
g =(x * x for x inrange(10))
Summary: A generator is a high-level iterator. The advantage of the generator is that it delays the calculation and returns one result at a time, which is very suitable for calculations with large amounts of data. However, one thing you must pay attention to when using a generator is that the generator can only be traversed once.
Lambda expressions are designed purely for the purpose of writing simple functions, and play a function of shorthand, making simple functions more concise.
The difference between lambda and def
Lambda expressions can save the process of defining functions, make the code more concise, suitable for simple functions, and write functions that deal with larger businesses need to use def definitions.
Lambda expressions are often used with map(), reduce(), filter() functions
# Convert numbers in a list to strings
map(str,[1,2,3,4,5,6])
reduce(): The function receives two parameters, one is a function and the other is a sequence. However, the function must receive two parameters reduce to continue the result and the next element of the sequence for cumulative calculations. The effect is reduce(f, [x1 , x2, x3, x4]) = f(f(f(x1, x2), x3), x4).
filter(): This function is used to filter, apply the passed function to each element in turn, and then decide whether to keep or discard the element according to whether the return value of the function is True or False.
The decorator is essentially a Python function, which allows other functions to add additional functions without any code changes. With decorators, we can extract a lot of similar code that has nothing to do with the function itself and continue to reuse it. It is often used in scenarios with aspect requirements: including inserting logs, performance testing, transaction processing, caching, and permission verification.
So why introduce decorators?
Scenario: Calculate the execution time of a function.
One method is to define a function to calculate the running time of the function, and then process the real business code after the running time calculation is completed. The code is as follows:
import time
def get_time(func):
startTime = time.time()func()
endTime = time.time()
processTime =(endTime - startTime)*1000
print "The function timing is %f ms"%processTime
def myfunc():
print "start func"
time.sleep(0.8)
print "end func"get_time(myfunc)myfunc()
But the logic of this code destroys the original code logic, that is, calls to all func functions need to be implemented using get_time(func).
So, is there a better way to display it? Of course there is, that is the decorator.
Write a simple decorator
Combine the above examples to write a decorator:
def get_time(func):
def wrapper():
startTime = time.time()func()
endTime = time.time()
processTime =(endTime - startTime)*1000
print "The function timing is %f ms"%processTime
return wrapper
print "myfunc is:", myfunc.__name__
myfunc =get_time(myfunc)
print "myfunc is: ", myfunc.__name__
myfunc()
In this way, a simple and complete decorator is implemented. It can be seen that the decorator does not affect the execution logic and call of the function.
In Python, you can use "@" syntactic sugar to streamline the decorator code. Change the above example to:
@ get_time
def myfunc():
print "start func"
time.sleep(0.8)
print "end func"
print "myfunc is: ", myfunc.__name__
myfunc()
** Calling order of decorators**
Decorators can be used in stacks. If multiple decorators decorate a function at the same time, the call order of the decorators is opposite to the declaration order of @ Syntax Sugar, that is:
@ decorator1
@ decorator2
def func():
pass
equal to:
func = decorator1(decorator2(func()))
Decorated function takes parameters
In the above example, myfunc() has no parameters. If you add parameters, how to write the decorator?
# Decorated function with parameters
def get_time3(func):
def wrapper(*args,**kwargs):
startTime = time.time()func(*args,**kwargs)
endTime = time.time()
processTime =(endTime - startTime)*1000
print "The function timing is %f ms"%processTime
return wrapper
@ get_time3
def myfunc2(a):
print "start func"
print a
time.sleep(0.8)
print "end func"
a ="test"myfunc2(a)
Decorator with parameters
The decorator has great flexibility, and it supports parameters. For example, in the above example, the only parameter of the @get_time decorator is the function to execute the business. Of course, you can also add parameters to the decorator for logical judgment.
In Python, common class decorators include: @staticmathod, @classmethod and @property
The above is the advanced usage of Python compiled this time, and this article will continue to be updated.
Recommended Posts