python高级应用_5个高级Python概念:解释和应用

python高级应用

When you have developed a good understanding of basic data structures and their key functionalities, it’s time to explore some more advanced techniques in Python. In this article, I’d like to review five concepts that you can take advantage of in your code.

当您对基本数据结构及其关键功能有了很好的了解后,就该探索一些更高级的Python技术了。 在本文中,我想回顾一下可以在代码中利用的五个概念。

1. Lambda函数 (1. Lambda Functions)

Lambda functions are also called anonymous functions in Python. Some people simply refer to them as lambdas. They have the following syntax: lambda arguments: expression. In essence, we use the lambda keyword to signify the declaration of a lambda function. Then we list the arguments, the number of which can be zero or more. After the colon, we list the expression that uses these arguments for any applicable operations.

Lambda函数在Python中也称为匿名函数。 有些人只是将它们称为lambda。 它们具有以下语法: lambda arguments: expression 。 本质上,我们使用lambda关键字来表示lambda函数的声明。 然后我们列出参数,其数量可以为零或更多。 在冒号之后,我们列出了将这些参数用于任何适用操作的表达式。

Lambda functions are particularly useful in cases where we need to have a short one-time use function. For instance, several built-in functions have the key argument, to which we can set a lambda function.

在需要短时间的一次性使用功能的情况下,Lambda函数特别有用。 例如,几个内置函数具有key参数,我们可以向其设置lambda函数。

>>> # Declare a list of tuples
>>> scores = [('John', 95), ('Danny', 98), ('Aaron', 90), ('Leo', 94)]
>>> # Sort using the default order of the tuples
>>> sorted(scores, reverse=True)
[('Leo', 94), ('John', 95), ('Danny', 98), ('Aaron', 90)]
>>> # Sort using the scores
>>> sorted(scores, key=lambda x: x[1], reverse=True)
[('Danny', 98), ('John', 95), ('Leo', 94), ('Aaron', 90)]

In the above code, we wanted to sort a list of tuples. By default, the tuples will be sorted based on each of the items contained. In this case, the sorting was based on the names’ first letters. However, we wanted to solve by the scores, which are the second items of the tuples. To accomplish it, we took advantage of the lambda function, in which the x argument refers to each tuple that was to be sorted. Because the score was the second item in each tuple, we just needed to specify the index of 1 to access the second item.

在上面的代码中,我们想要对元组列表进行排序。 默认情况下,将基于包含的每个项目对元组进行排序。 在这种情况下,排序基于名称的首字母。 但是,我们想通过分数来解决,这是元组的第二项。 为了实现它,我们利用了lambda函数,其中x参数指向要排序的每个元组。 因为分数是每个元组中的第二个项目,所以我们只需要指定索引1即可访问第二个项目。

2.理解力 (2. Comprehensions)

Probably the most Pythonic example that is mentioned a lot is the comprehension technique. In essence, this technique allows us to create a list, dictionary, or set using an exiting iterable, which are named list comprehension, dictionary comprehension, and set comprehension, respectively. The following code snippet shows you these usages.

可能被大量提及的最Python化的例子是理解技术。 本质上,该技术允许我们使用现有的iterable创建列表,字典或集合 ,分别将其命名为列表理解,字典理解和集合理解。 以下代码片段向您展示了这些用法。

>>> # Create a list to be used in comprehensions
>>> numbers = [1, 2, 3, -3, -2, -1]
>>> # Create a new list of these numbers' squares
>>> [x*x for x in numbers]
[1, 4, 9, 9, 4, 1]
>>> # Create a new dictionary of these numbers' exponentiation
>>> {x: pow(10, x) for x in numbers}
{1: 10, 2: 100, 3: 1000, -3: 0.001, -2: 0.01, -1: 0.1}
>>> # Create a set of these numbers' absolutes
>>> {abs(x) for x in numbers}
{1, 2, 3}

The syntax of these comprehensions looks similar. Here’s a quick highlight of the differential forms. It should be noted that you can add conditions to keep the items you need.

这些理解的语法看起来相似。 这是差异形式的简要介绍。 应该注意的是,您可以添加条件来保留所需的项目。

List Comprehension: [expr for x in iterable]Dictionary Comprehension: {key_expr: value_expr for x in iterable}Set Comprehension: {expr for x in iterable}With Optional Conditions:
[expr for x in iterable if condition]
{key_expr: value_expr for x in iterable if condition}
{expr for x in iterable if condition}

Instead of implementing for-loops, these comprehensions are very handy to create these container data types. More importantly, they’re usually faster than the for-loops, and thus they’re more performant and should be the preferred way for these operations.

这些理解而不是实现for循环,对于创建这些容器数据类型非常方便。 更重要的是, 它们通常比for循环快,因此它们的性能更高 ,应该是这些操作的首选方式。

3.发电机 (3. Generators)

Previously, I’ve mentioned iterables, which refer to Python objects that can be iterated. During the iteration, the iterable is converted to an iterator, such that the iterator can render elements when needed. One particular kind of iterator is a generator. Unlike typical iterables, such as lists and dictionaries — which have all their elements loaded in the memory — generators produce elements in a lazy fashion without the need of loading all elements in the memory, and thus they’re memory-efficient iterables. A trivial example is shown in the following code snippet.

之前,我曾提到过可迭代对象,它是指可以迭代的Python对象。 在迭代过程中,可迭代对象将转换为迭代器,以便迭代器可以在需要时呈现元素。 一种特殊的迭代器是生成器。 与典型的可迭代变量(如列表和字典)一样,所有元素都已加载到内存中,生成器以惰性方式生成元素,而无需将所有元素都加载到内存中,因此它们是内存有效的可迭代对象。 下面的代码片段显示了一个简单的示例。

>>> # A trivial generator function
... def abc_generator():
...     yield "a"
...     yield "b"
...     yield "c"
... 
... 
... abc_gen = abc_generator()
... print("Type of abc_gen:", type(abc_gen))
... for letter in abc_gen:
...     print(letter)
... 
Type of abc_gen: <class 'generator'>
a
b
c

As you can see, the generator function makes a generator involving the use of the yield keyword. During iteration, these elements are rendered sequentially.

如您所见,generator函数使生成器涉及yield关键字的使用。 在迭代过程中,将依次渲染这些元素。

One practical use case of generators is to deal with a large amount of data — when all loaded, it can slow down the computer or simply can’t be loaded at all because of an enormously large size. For instance, a trivial example would be to calculate the sum of integers 1–10,000,000,000. I tried 1 billion on my computer and found out that the size was about 8 GB. So, 10 billion would be about 80 GB if I had tried it, which would probably crash the program or even my computer. Without being able to create the list, it was impossible for me to calculate the sum using the list. In this case, we should consider generators.

生成器的一个实际用例是处理大量数据-加载全部数据后,它可能会减慢计算机速度,或者由于容量巨大而根本无法加载。 例如,一个简单的例子是计算1–10,000,000,000的整数之和。 我在计算机上尝试了10亿个,发现大小约为8 GB。 因此,如果我尝试使用100亿个内存,则大约需要80 GB,这可能会使程序甚至计算机崩溃。 无法创建列表,我无法使用列表来计算总和。 在这种情况下,我们应该考虑发电机。

limit = 10000000000


# Use a generator function
def integer_generator():
    n = 0
    while n < limit:
        n += 1
        yield n




int_gen = integer_generator()
int_sum0 = sum(int_gen)


# Use generator expression
int_sum1 = sum(x for x in range(1, limit+1))

As shown above, we can create a generator that produces an integer once at a time, which is memory-efficient. The above code snippet shows you another useful technique called generator expression, which has the following format: (expr for item in iterable).

如上所示,我们可以创建一个生成器,一次生成一个整数,这样可以节省内存。 上面的代码片段向您展示了另一种有用的技术,称为生成器表达式,该格式具有以下格式:( (expr for item in iterable)

4.装饰器 (4. Decorators)

Decorators are higher-order functions that modify other functions’ behavior without affecting their core functionalities. You can think of other functions as plain donuts; the decoration is the process of applying coatings to the donuts. No matter how you decorate them, they’re still donuts. In other words, decorators are just to add some tweaks in terms of the functions’ look or some other non-essential aspects without changing their internal algorithm. Let’s look at decorators with a trivial example.

装饰器是高阶函数,可以在不影响其核心功能的情况下修改其他功能的行为。 您可以将其他功能视为普通的甜甜圈。 装饰是在甜甜圈上涂上涂料的过程。 无论您如何装饰它们,它们仍然是甜甜圈。 换句话说,装饰器只是在不改变其内部算法的情况下,对函数的外观或其他一些非必要方面进行了一些调整。 让我们用一个简单的例子来看装饰器。

from functools import wraps
import time




def timing(func):
    @wraps(func)
    def wrapped(*args, **kwargs):
        start = time.time()
        func(*args, **kwargs)
        end = time.time()
        print(f"Time Elapsed: {end-start}")


    return wrapped


@timing
def sum_of_squares(n):
    int_sum = sum(x*x for x in range(n))
    print(f"Sum of Squares from 1 to {n}: {int_sum}")

The above example shows you how to declare a decorator function and how to use it to decorate other functions. As you can see, the decorator function timing takes another function as a parameter, which logs the running time of the decorated function. Notably, the decorated function returns the function as its output. To use the decorator, we simply place it above another function’s top by using a @ sign as a prefix, which signals that the following declared function is decorated by this specified decorator function. The following code shows you what the decoration is like.

上面的示例显示了如何声明装饰器函数以及如何使用它来装饰其他函数。 如您所见,装饰器函数timing将另一个函数作为参数,它记录了装饰函数的运行时间。 值得注意的是,修饰函数将函数作为其输出返回。 要使用装饰器,我们只需使用@符号作为前缀将其放置在另一个函数的顶部即可,这表示以下声明的函数已由此指定的装饰器函数装饰。 下面的代码向您展示装饰的样子。

>>> sum_of_squares(100)
... sum_of_squares(10000000)
... 
Sum of Squares from 1 to 100: 328350
Time Elapsed: 4.601478576660156e-05
Sum of Squares from 1 to 10000000: 333333283333335000000
Time Elapsed: 1.0669260025024414

One thing that I found out that many tutorials on decorators failed to mention is the use of @wraps decorator in the declaration of a decorator function. I highly recommend using it (see Line 6 of the previous code snippet), for various reasons that have been covered in my previous blog article.

我发现很多关于装饰器的教程没有提及的一件事是在装饰器函数的声明中使用了@wraps装饰器。 出于各种原因,我强烈建议您使用它(请参阅前面的代码片段的第6行)。

5.易处理性 (5. Hashability)

When we learn Python dictionaries, we get to know that the keys need to be hashable. What does hashable mean? Hashable simply means a particular Python object can be hashed, the process of which is known as hashing. The following diagram shows you a simplified flow of how hashing works.

当我们学习Python字典时,我们知道键必须是可哈希的。 hashable是什么意思? 可散列只是意味着可以对特定的Python对象进行散列,其过程称为散列。 下图向您显示了哈希工作原理的简化流程。

Image for post
Wikipedia, Public Domain) 维基百科 ,公共领域)

Essentially, hashing is the process of using a hash function (sometimes referred to as hasher) to convert Python objects (called keys in the diagram) to numeric hashed values (called hashes in the diagram). A quick way to know if a particular Python object is to use the built-in hash() function to fetch the hash value. If the object is not hashable, Python will raise a TypeError exception for us.

本质上,哈希是使用哈希函数(有时称为哈希)将Python对象(在图中称为键)转换为数字哈希值(在图中称为哈希)的过程。 一种了解特定Python对象是否快速的方法是使用内置的hash()函数来获取哈希值。 如果对象不可哈希,Python将为我们TypeError异常。

>>> # Get an string object's hash value
>>> hash("Hello World!")
5892830027481816904
>>> 
>>> # Get a tuple object's hash value
>>> hash((2, 'Hello'))
-4798835419149360612
>>> 
>>> # Get a list object's hash value
>>> hash([1, 2, 3])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>>> 
>>> # Get a dict object's hash value
>>> hash({"a": 1, "b": 2})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'

Notably, hashing takes time and can be slower than building lists and tuples. So the question is — why do we bother implementing dictionaries using hashing? On a related note, you may have heard that the elements in a set need to be hashable too. Under the hood, both creating dictionaries and sets require the building of hash tables. The following code snippet shows you how the hashability of particular objects may affect their qualifications to be used as dictionary keys.

值得注意的是,散列要花费时间,并且可能比构建列表和元组慢。 所以问题是–为什么我们要麻烦使用散列来实现字典? 与此相关的是,您可能听说过集合中的元素也需要可散列。 在后台,创建字典和集合都需要构建哈希表。 下面的代码片段向您展示了特定对象的哈希性如何影响它们用作字典键的资格。

The biggest advantage of using hashes is instant look-up time (i.e., O(1) time complexity) for fetching an element in the dictionary. Similarly, checking whether a particular item is in the set takes a constant time, too. In other words, using hashing as the implementation mechanism provides high efficiency for various common operations, such as item retrieving, item insertion, and item checking, at the expense of the overhead of having the hash table under the hood.

使用哈希的最大优点是用于在字典中获取元素的即时查找时间(即O(1)时间复杂度)。 同样,检查特定项目是否在集合中也需要花费固定的时间。 换句话说,使用散列作为实现机制为各种常见操作(例如,项检索,项插入和项检查)提供了高效率,但代价是将哈希表置于后台。

>>> import random
... import timeit
... 
... 
... # Create a function to check the look up time
... def dict_look_up_time(n):
...     numbers = list(range(n))
...     random.shuffle(numbers)
...     d0 = {x: str(x) for x in numbers}
...     random_int = random.randint(0, n - 1)
...     t0 = timeit.timeit(lambda: d0[random_int], number=10000)
...     return t0
... 
... 
... for n in (10, 100, 1000, 10000, 100000):
...     elapse_time = dict_look_up_time(n)
...     print(f"*** N = {n:<8}: {elapse_time:.5f}")
... 
*** N = 10      : 0.00114
*** N = 100     : 0.00256
*** N = 1000    : 0.00291
*** N = 10000   : 0.00207
*** N = 100000  : 0.00286

To mimic a real situation, we generate some random integers to get an average lookup time for item fetching. As you can see, even with 100,000 items in the dictionary, the lookup time stays about the same, which highlights the advantage of implementing a hash table as the storage mechanism for the dictionaries.

为了模拟实际情况,我们生成一些随机整数以获取项目获取的平均查找时间。 如您所见,即使字典中有100,000个项目,查找时间也保持不变,这凸显了实现将哈希表作为字典的存储机制的优势。

结论 (Conclusions)

In this article, we reviewed five advanced concepts in Python. Here’s a quick recap of the most key takeaway information.

在本文中,我们回顾了Python中的五个高级概念。 这是最关键的外卖信息的快速回顾。

  • Lambda functions. You use lambda functions to have a simple operation, usually within another function call, such as sorted() or max().

    Lambda函数。 您通常使用lambda函数进行简单的操作,通常是在另一个函数调用中进行,例如sorted()max()

  • Comprehensions. They’re convenient and performant ways to create lists, dictionaries, and sets from iterables.

    理解力。 它们是从可迭代对象创建列表,字典和集合的便捷高效的方法。

  • Generators. Generators are lazily-evaluated iterators that render items only when requested, and thus they’re very memory efficient. They should be used when you’re dealing with a large amount of data sequentially.

    发电机。 生成器是延迟评估的迭代器,它们仅在被请求时才呈现项目,因此它们的内存效率很高。 当您顺序处理大量数据时,应使用它们。

  • Decorators. Decorators are useful when you want to have some non-algorithmic modifications with current functions. In addition, decorators can be used repeatedly. Once defined, they can decorate as many functions as you want.

    装饰器。 当您想对当前函数进行一些非算法修改时,装饰器很有用。 此外,装饰器可以重复使用。 定义后,它们可以装饰所需的任意多个功能。

  • Hashability. Hashability is the required characteristic of Python objects that can be used as dictionary keys or set elements. They provide a mechanism for efficient item retrieving and insertion, as well as membership checking.

    易用性。 哈希性是可以用作字典键或set元素的Python对象的必需特性。 它们提供了一种有效的项目检索和插入以及成员资格检查的机制。

翻译自: https://medium.com/better-programming/5-advanced-python-concepts-explanations-and-applications-99a03f6bd1bd

python高级应用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值