Maison > développement back-end > Tutoriel Python > Les compréhensions de listes de Python sont-elles un moyen efficace de résoudre la tâche ?

Les compréhensions de listes de Python sont-elles un moyen efficace de résoudre la tâche ?

WBOY
Libérer: 2023-04-13 22:19:01
avant
1539 Les gens l'ont consulté

Les compréhensions de listes de Python sont-elles un moyen efficace de résoudre la tâche ?

Python est un langage de programmation extrêmement diversifié et puissant ! Lorsqu’un problème doit être résolu, il existe différentes approches.

Avantages de la compréhension de liste

  • Cela permet d'économiser plus de temps et d'espace que les boucles.
  • Nécessite moins de lignes de code.
  • Convertissez les instructions d'itération en formules.

Comment créer une liste en Python

La compréhension de liste est une structure syntaxique qui crée une liste basée sur une liste existante. Examinons les différentes implémentations de création de listes

Boucles

Les boucles sont la manière traditionnelle de créer des listes. Quel que soit le type de boucle que vous utilisez. Pour créer une liste de cette façon, vous devez :

  1. Instancier une liste vide.
  2. Parcourez les éléments d'un itérable (comme une plage).
  3. Ajoutez chaque élément à la fin de la liste.
numbers = []
for number in range(10):
numbers.append(number)
print(numbers)
Copier après la connexion

Sortie :

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Copier après la connexion
Copier après la connexion

Dans cet exemple, vous instanciez une liste vide de nombres. Utilisez ensuite une boucle for pour parcourir range(10) et ajoutez chaque numéro à la fin de la liste à l’aide de la méthode append(). Objet

map()

map() est une autre façon de créer une liste. Vous devez transmettre à map() une fonction et un objet itérable, après quoi il crée un objet. Cet objet contient la sortie obtenue en exécutant chaque élément d'itération à l'aide de la fonction spécifiée.

Par exemple, il nous sera demandé d'ajouter la TVA au prix de certains produits.

VAT_PERCENT = 0.1# 10%
def add_vat(price):
return price + (price * VAT_PERCENT)
prices = [10.03, 8.6, 32.85, 41.5, 22.64]
grand_prices = map(add_vat, prices)
print(grand_prices)
grand_prices = list(grand_prices)
print(grand_prices)
Copier après la connexion

Vous avez construit la fonction add_vat() et créé l'objet itérable price. Vous transmettez les deux arguments à map() et collectez l'objet cartographique résultant grand_prices, ou vous pouvez facilement le convertir en liste à l'aide de list().

Sortie :

<map object at 0x7f18721e7400># map(add_vat, prices)
[11.03, 9.46, 36.14, 45.65, 24.9]# list(grand_prices)
Copier après la connexion

Compréhension de liste

Maintenant, regardons l'approche de compréhension de liste ! C'est en effet Pythonic et une meilleure façon de créer des listes. Pour voir à quel point cette approche est puissante, réécrivons l’exemple de boucle avec une seule ligne de code.

numbers = [number for number in range(10)]
print(numbers)
Copier après la connexion

Output

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Copier après la connexion
Copier après la connexion

Comme vous pouvez le constater, c'est une méthode incroyable ! La compréhension de la liste semble suffisamment lisible pour que vous n'ayez pas besoin d'écrire plus de code qu'une seule ligne.

Pour une meilleure compréhension des listes, consultez le format de syntaxe suivant :

new_list = [expression for member in iterable]
Copier après la connexion
Copier après la connexion

Quelle méthode est la plus efficace

D'accord, nous avons appris à utiliser les boucles, map() et les compréhensions de listes pour créer des listes dans votre La question "qui la méthode est plus efficace » peut venir à l’esprit. Analysons-le !

import random
import timeit
VAT_PERCENT = 0.1
PRICES = [random.randrange(100) for x in range(100000)]
def add_vat(price):
return price + (price * VAT_PERCENT)
def get_grand_prices_with_map():
return list(map(add_vat, PRICES))
def get_grand_prices_with_comprehension():
return [add_vat(price) for price in PRICES]
def get_grand_prices_with_loop():
grand_prices = []
for price in PRICES:
grand_prices.append(add_vat(price))
return grand_prices
print(timeit.timeit(get_grand_prices_with_map, number=100))
print(timeit.timeit(add_grand_prices_with_comprehension, number=100))
print(timeit.timeit(get_grand_prices_with_loop, number=100))
Copier après la connexion

Sortie :

0.9833468980004909# with_map
1.197223742999995 # with_comprehension
1.3564663889992516# with_loop
Copier après la connexion

Comme nous pouvons le voir maintenant, la meilleure façon de créer une liste est map(), la deuxième meilleure façon est la compréhension de la liste, et enfin la boucle.

Cependant, le choix de la méthode doit dépendre de ce que vous souhaitez réaliser.

  • L'utilisation de map() peut rendre votre code plus efficace.
  • L'utilisation de boucles peut rendre les idées de code plus claires.
  • L'utilisation de compréhensions de listes peut rendre votre code plus compact et efficace. C’est la meilleure façon de créer une liste car c’est la plus lisible.

Formules analytiques avancées

Logique conditionnelle

Plus tôt, je vous ai montré cette formule :

new_list = [expression for member in iterable]
Copier après la connexion
Copier après la connexion

La formule est peut-être un peu incomplète. Une description plus complète des expressions analytiques ajoute la prise en charge des conditions facultatives. La façon la plus courante d'ajouter une logique conditionnelle à une compréhension de liste est d'ajouter un conditionnel à la fin de l'expression :

new_list = [expression for member in iterable (if conditional)]
Copier après la connexion

Ici, votre instruction conditionnelle se trouve juste entre les parenthèses droites.

Les conditions sont importantes car elles permettent aux compréhensions de listes de filtrer les valeurs indésirables, ce qui est également possible dans le cas général en appelant filter() :

numbers = [number for number in range(20) if number % 2 == 0]
print(numbers)
Copier après la connexion

Sortie :

[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
Copier après la connexion

Comme vous pouvez le voir, cette analyse des nombres divisibles par 2 et n'ont aucun reste sont collectés.

Si vous avez besoin de filtres plus complexes, vous pouvez même déplacer la logique conditionnelle dans une fonction distincte.

def is_prime(number):
if number > 1:
for el in range(2, int(number/2)+1):
if (number % el) == 0:
return False
else:
return True
numbers = [number for number in range(20) if is_prime(number)]
print(numbers)
Copier après la connexion

Sortie :

[2, 3, 5, 7, 11, 13, 17, 19]
Copier après la connexion

Vous construisez is_prime(number) pour déterminer si un nombre est premier et renvoyez un booléen. Ensuite, vous devez ajouter la fonction à la condition de l'expression analytique.

Cette formule vous permet de choisir parmi plusieurs options de sortie possibles en utilisant une logique conditionnelle. Par exemple, vous avez une liste de prix de produits, s'il y a des nombres négatifs, vous devez les convertir en nombres positifs :

price_list = [1.34, 19.01, -4.2, 6, 8.78, -1,1]
normalized_price_list = [price if price > 0 else price*-1 for price in price_list]
print(normalized_price_list)
Copier après la connexion

Résultat :

[1.34, 19.01, 4.2, 6, 8.78, 1,1]
Copier après la connexion
Copier après la connexion

Ici, votre expression prix a une instruction conditionnelle si prix > 0 sinon prix* -1 . Cela indique à Python d'afficher la valeur du prix si le prix est positif, mais de convertir le prix en une valeur positive si le prix est négatif. Cette fonctionnalité est puissante, et il est vraiment utile de considérer la logique conditionnelle comme sa propre fonction :

def normalize_price(price):
return price if price > 0 else price*-1
price_list = [1.34, 19.01, -4.2, 6, 8.78, -1,1]
normalized_price_list = [normalize_price(price) for price in price_list]
print(normalized_price_list)
Copier après la connexion

Sortie :

[1.34, 19.01, 4.2, 6, 8.78, 1,1]
Copier après la connexion
Copier après la connexion

Expression définie

Vous pouvez également créer une expression définie ! C'est fondamentalement la même chose qu'une compréhension de liste. La différence est que l'expression définie ne contient aucun doublon. Vous pouvez créer des expressions définies en utilisant des accolades au lieu de crochets :

string = "Excellent"
unique_string = {letter for letter in string}
print(unique_string)
Copier après la connexion

Résultat :

{"E", "e", "n", "t", "x", "c", "l"}
Copier après la connexion

你的集合解析式只包含唯一的字母。这与列表不同,集合不保证项目将以特定顺序存储数据。这就是为什么集合输出的第二个字母是 e,即使字符串中的第二个字母是 x。

字典解析式

字典解析式也是是类似的,但需要定义一个键:

string = "Words are but wind"
word_order = {el: ind+1 for ind, el in enumerate(string.split())}
print(word_order)
Copier après la connexion

输出:

{"Words": 1, "are": 2, "but": 3, "wind": 4}
Copier après la connexion

要创建 word_order 字典,请在表达式中使用花括号 ({}) 以及键值对 (el: ind+1)。

海象运算符

Python 3.8 中引入的海象运算符允许您一次解决两个问题:为变量赋值,返回该值。

假设您需要对将返回温度数据的 API 应用十次。您想要的只是 100 华氏度以上的结果。而每个请求可能都会返回不同的数据。在这种情况下,没有办法在 Python 中使用列表解析式来解决问题。可迭代成员(如果有条件)的公式表达式无法让条件将数据分配给表达式可以访问的变量。

海象运算符解决了这个问题。它允许您在执行表达式的同时将输出值分配给变量。以下示例显示了这是如何实现的,使用 get_weather_data() 生成伪天气数据:

import random
def get_weather_data():
return random.randrange(90, 110)
hot_temps = [temp for item in range(20) if (temp := get_weather_data()) >= 100]
print(hot_temps)
Copier après la connexion

输出:

[108, 100, 106, 103, 108, 106, 103, 104, 109, 106]
Copier après la connexion

什么时候不要使用解析式

列表解析式非常有用,它可以帮助您编写清晰且易于阅读和调试的代码。但在某些情况下,它们可能会使您的代码运行速度变慢或使用更多内存。如果它让您的代码效率更低或更难理解,那么可以考虑选择另一种方式。

注意嵌套的解析式

可以通过嵌套解析式以创建列表、字典和集合的组合集合(译者注:这个集合不是指 set 对象类型,而是 collection,泛指容器)。例如,假设一家公司正在跟踪一年中五个不同城市的收入。存储这些数据的完美数据结构可以是嵌套在字典解析式中的列表解析式。

cities = ['New York', 'Oklahoma', 'Toronto', 'Los Angeles', 'Miami']
budgets = {city: [0 for x in range(12)] for city in cities}
print(budgets)
Copier après la connexion

输出:

{
"NewYork": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
"Oklahoma": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
"Toronto": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
"LosAngeles": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
"Miami": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
}
Copier après la connexion

您使用字典解析式创建了 budgets 容器。该表达式是一个键值对,其中包含另一个解析式。此代码将快速生成城市中每个 city 的数据列表。

嵌套列表是创建矩阵的常用方法,通常用于数学目的。查看下面的代码块:

matrix = [[x for x in range(7)] for y in range(6)]
print(matrix)
Copier après la connexion

输出:

[
[0, 1, 2, 3, 4, 5, 6],
[0, 1, 2, 3, 4, 5, 6],
[0, 1, 2, 3, 4, 5, 6],
[0, 1, 2, 3, 4, 5, 6],
[0, 1, 2, 3, 4, 5, 6],
[0, 1, 2, 3, 4, 5, 6]
]
Copier après la connexion

外部列表解析式 [... for y in range(6)] 创建了六行,而内部列表解析式 [x for x in range(7)] 将用值填充这些行中的每一行。

到目前为止,每个嵌套解析式的目标都是真正且直观的。但是,还有一些其他情况,例如创建扁平化的嵌套列表,其中的逻辑可以使您的代码非常难以阅读。让我们看下面的例子,使用嵌套列表解析式来展平一个矩阵:

matrix = [
[0, 1, 0],
[1, 0, 1],
[2, 1, 2],
]
flat = [num for row in matrix for num in row]
print(flat)
Copier après la connexion

输出:

[0, 1, 0, 1, 0, 1, 2, 1, 2]
Copier après la connexion
Copier après la connexion

扁平化矩阵的代码确实很简洁,但是太难理解了,您应该花点时间弄清楚它是如何工作的。另一方面,如果您使用 for 循环来展平相同的矩阵,那么您的代码将更加简单易读:

matrix = [
[0, 1, 0],
[1, 0, 1],
[2, 1, 2],
]
flat = []
for row in matrix:
for num in row:
flat.append(num)
print(flat)
Copier après la connexion

输出:

[0, 1, 0, 1, 0, 1, 2, 1, 2]
Copier après la connexion
Copier après la connexion

现在,您可以看到代码一次遍历矩阵的一行,在移动到下一行之前取出该行中的所有元素。

虽然嵌套列表解析式可能看起来更具有 Python 风格,但对于能够编写出您的团队可以轻松理解和修改的代码来才是更加最重要的。当选择一个方法时,您应该根据解析式是有助于还是有损于可读性来做出相应的判断。

为大型数据集使用生成器

Python 中的列表解析式通过将整个列表存储到内存中来工作。对于小型至中型列表这通常很好。如果您想将前一千个整数相加,那么列表解析式将轻松地解决此任务:

summary = sum([x for x in range(1000)])
print(summary)
Copier après la connexion

输出:499500

但是,如果您需要对十亿个数字求和呢?您可以尝试执行此操作,但您的计算机可能不会有响应。这是可能因为计算机中分配大量内存。也许您是因为计算机没有如此多的内存资源。

例如,你想要一些第一个十亿整数,那么让我们使用生成器!这可能多需要一些时间,但计算机应该可以克服它:

summary = sum((x for x in range(1000000000)))
print(summary)
Copier après la connexion

输出:

499999999500000000
Copier après la connexion

让我们来对比一下哪种方法是更优的!

import timeit
def get_sum_with_map():
return sum(map(lambda x: x, range(1000000000)))
def get_sum_with_generator():
return sum((x for x in range(1000000000)))
print(timeit.timeit(get_sum_with_map, number=100))
print(timeit.timeit(get_sum_with_generator, number=100))
Copier après la connexion

输出:

4940.844053814# get_sum_with_map
3464.1995523349997# get_sum_with_generator
Copier après la connexion

正如您所见,生成器比 map() 高效得多。

总结

本文向您介绍了列表解析式,以及如何使用它来解决复杂的任务,而不会使您的代码变得过于困难。

现在你:

  • J'ai appris plusieurs façons alternatives de créer des listes.
  • Découvrez les avantages de chaque méthode.
  • Peut simplifier les boucles et les appels map() pour lister les compréhensions.
  • Compris une manière d'ajouter une logique conditionnelle aux expressions analytiques.
  • Peut créer des ensembles et des expressions de dictionnaire.
  • J'ai appris quand ne pas utiliser d'expressions analytiques.

Merci d'avoir lu cet article jusqu'à la fin ! Si cet article vous a été utile, laissez un commentaire et n'oubliez pas de cliquer sur « Suivre » pour vous assurer de ne pas manquer mes articles ! Vos activités sont ma joie ! Bonne chance!

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:51cto.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal