Heim  >  Artikel  >  Backend-Entwicklung  >  Wie verwende ich die Python-Listenanalyse?

Wie verwende ich die Python-Listenanalyse?

王林
王林nach vorne
2023-04-16 21:10:06820Durchsuche

Python ist eine äußerst vielfältige und leistungsstarke Programmiersprache! Wenn ein Problem gelöst werden muss, gibt es unterschiedliche Ansätze. In diesem Artikel wird das Listenverständnis demonstriert. Wir besprechen, wie man es benutzt? Wann sollte es verwendet werden bzw. wann nicht?

Wie verwende ich die Python-Listenanalyse?

Vorteile des Listenverständnisses

  • Es spart Zeit und Platz als Schleifen.
  • Benötigt weniger Codezeilen.
  • Konvertieren Sie Iterationsanweisungen in Formeln.

So erstellen Sie eine Liste in Python

Listenverständnis ist eine Syntaxstruktur, die eine Liste basierend auf einer vorhandenen Liste erstellt. Schauen wir uns die verschiedenen Implementierungen zum Erstellen von Listen an.

Schleifen

Schleifen sind die traditionelle Art, Listen zu erstellen. Egal welche Art von Schleife Sie verwenden. Um auf diese Weise eine Liste zu erstellen, sollten Sie:

  1. eine leere Liste instanziieren.
  2. Durchlaufen Sie die Elemente eines iterierbaren Elements (z. B. Bereich).
  3. Hängen Sie jedes Element an das Ende der Liste an.
numbers = []
for number in range(10):
numbers.append(number)

print(numbers)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

In diesem Beispiel instanziieren Sie eine leere Liste von Zahlen. Verwenden Sie dann eine for-Schleife, um den Bereich (10) zu durchlaufen und jede Zahl mit der Methode append() an das Ende der Liste anzuhängen. Das

map()-Objekt

map()​ ist eine weitere Möglichkeit, eine Liste zu erstellen. Sie müssen map() eine Funktion und ein iterierbares Objekt übergeben und anschließend ein Objekt erstellen. Dieses Objekt enthält die Ausgabe, die durch die Ausführung jedes Iterationselements mit der angegebenen Funktion erhalten wird.

Zum Beispiel wird uns die Aufgabe gestellt, die Mehrwertsteuer auf den Preis bestimmter Produkte aufzuschlagen.

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)

Sie haben die Funktion add_vat()​ erstellt und das iterierbare Preisobjekt erstellt. Sie übergeben beide Argumente an map() und sammeln das resultierende Kartenobjekt grand_prices , oder Sie können es einfach mit list() in eine Liste konvertieren.

<map object at 0x7f18721e7400># map(add_vat, prices)
[11.03, 9.46, 36.14, 45.65, 24.9]# list(grand_prices)

Listenverständnis

Schauen wir uns nun den Ansatz des Listenverständnisses an! Dies ist in der Tat Pythonic und eine bessere Möglichkeit, Listen zu erstellen. Um zu sehen, wie leistungsstark dieser Ansatz ist, schreiben wir das Schleifenbeispiel mit einer einzigen Codezeile neu.

numbers = [number for number in range(10)]
print(numbers)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Wie Sie sehen, ist das eine unglaubliche Methode! Das Listenverständnis scheint so lesbar zu sein, dass Sie nicht mehr Code als nur eine Zeile schreiben müssen.

Für ein besseres Verständnis von Listen sehen Sie sich das folgende Syntaxformat an:

new_list = [expression for member in iterable]

Welche Methode ist effizienter?

Okay, wir haben gelernt, wie man Schleifen, map() und Listenverständnisse verwendet, um Listen in Ihrer Frage zu erstellen „Methode ist effektiver“ mag einem in den Sinn kommen. Lass es uns analysieren!

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))
0.9833468980004909# with_map
1.197223742999995 # with_comprehension
1.3564663889992516# with_loop

Wie wir jetzt sehen können, ist map() der beste Weg, eine Liste zu erstellen, der zweitbeste Weg ist das Listenverständnis und schließlich die Schleife.

Die Wahl der Methode sollte jedoch davon abhängen, was Sie erreichen möchten.

  • Die Verwendung von map() kann Ihren Code effizienter machen.
  • Die Verwendung von Schleifen kann die Codeideen klarer machen.
  • Die Verwendung von Listenverständnissen kann Ihren Code kompakter und effizienter machen. Dies ist die beste Möglichkeit, eine Liste zu erstellen, da sie am besten lesbar ist.

Erweiterte analytische Formeln

Bedingte Logik

Zuvor habe ich Ihnen diese Formel gezeigt:

new_list = [expression for member in iterable]

Die Formel ist möglicherweise etwas unvollständig. Eine ausführlichere Beschreibung analytischer Ausdrücke fügt Unterstützung für optionale Bedingungen hinzu. Die gebräuchlichste Methode, bedingte Logik zu einem Listenverständnis hinzuzufügen, besteht darin, am Ende des Ausdrucks eine Bedingung hinzuzufügen:

new_list = [expression for member in iterable (if conditional)]

Hier steht Ihre bedingte Anweisung direkt in der rechten Klammer.

Bedingungen sind wichtig, weil sie es Listenverständnissen ermöglichen, unerwünschte Werte herauszufiltern, was im allgemeinen Fall auch durch den Aufruf von filter() erfolgen kann:

numbers = [number for number in range(20) if number % 2 == 0]
print(numbers)
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

Wie Sie sehen können, sammelt dieses Verständnis die Werte, die verwendet werden können durch 2 Eine Zahl, die teilbar ist und keinen Rest hat.

Wenn Sie komplexere Filter benötigen, können Sie die bedingte Logik sogar in eine separate Funktion verschieben.

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)
[2, 3, 5, 7, 11, 13, 17, 19]

Sie konstruieren is_prime(number), um zu bestimmen, ob eine Zahl eine Primzahl ist, und um einen booleschen Wert zurückzugeben. Als nächstes sollten Sie die Funktion zur Bedingung des analytischen Ausdrucks hinzufügen.

Mit dieser Formel können Sie mithilfe der bedingten Logik aus mehreren möglichen Ausgabeoptionen auswählen. Sie haben beispielsweise eine Produktpreisliste und wenn es negative Zahlen gibt, sollten Sie diese in positive Zahlen umwandeln:

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)
[1.34, 19.01, 4.2, 6, 8.78, 1,1]

Hier hat Ihr Ausdruck „Preis“ eine bedingte Anweisung, wenn Preis > 0, sonst Preis*-1. Dies weist Python an, den Preiswert auszugeben, wenn der Preis positiv ist, den Preis jedoch in einen positiven Wert umzuwandeln, wenn der Preis negativ ist. Diese Funktion ist leistungsstark und es ist wirklich nützlich, sich bedingte Logik als eine eigene Funktion vorzustellen:

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)
[1.34, 19.01, 4.2, 6, 8.78, 1,1]

集合解析式

您还可以创建一个集合解析式!它基本与列表解析式相同。不同之处在于集合解析式不包含重复项。您可以通过使用花括号取代方括号来创建集合解析式:

string = "Excellent"
unique_string = {letter for letter in string}
print(unique_string)
{"E", "e", "n", "t", "x", "c", "l"}

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

字典解析式

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

string = "Words are but wind"
word_order = {el: ind+1 for ind, el in enumerate(string.split())}
print(word_order)
{"Words": 1, "are": 2, "but": 3, "wind": 4}

要创建 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)
[108, 100, 106, 103, 108, 106, 103, 104, 109, 106]

什么时候不要使用解析式

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

注意嵌套的解析式

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

cities = ['New York', 'Oklahoma', 'Toronto', 'Los Angeles', 'Miami']
budgets = {city: [0 for x in range(12)] for city in cities}
print(budgets)
{
"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]
}

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

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

matrix = [[x for x in range(7)] for y in range(6)]
print(matrix)
[
[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]
]

外部列表解析式 [... 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)
[0, 1, 0, 1, 0, 1, 2, 1, 2]

扁平化矩阵的代码确实很简洁,但是太难理解了,您应该花点时间弄清楚它是如何工作的。另一方面,如果您使用 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)
[0, 1, 0, 1, 0, 1, 2, 1, 2]

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

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

为大型数据集使用生成器

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

summary = sum([x for x in range(1000)])
print(summary)
499500

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

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

summary = sum((x for x in range(1000000000)))
print(summary)
499999999500000000

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

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))
4940.844053814# get_sum_with_map
3464.1995523349997# get_sum_with_generator

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

总结

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

Jetzt:

  • Sie haben mehrere alternative Möglichkeiten zum Erstellen von Listen kennengelernt.
  • Finden Sie die Vorteile jeder Methode heraus.
  • Kann Schleifen und map()-Aufrufe vereinfachen, um Verständnisse aufzulisten.
  • Ich habe eine Möglichkeit verstanden, analytischen Ausdrücken bedingte Logik hinzuzufügen.
  • Kann Mengen und Wörterbuchausdrücke erstellen.
  • Ich habe gelernt, wann ich keine analytischen Ausdrücke verwenden sollte.

Das obige ist der detaillierte Inhalt vonWie verwende ich die Python-Listenanalyse?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:51cto.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen