目錄
列表解析式的優點
如何在Python中建立清單
循環
map() 物件
列表解析式
哪種方法更有效
高級解析式
條件邏輯
集合解析式
字典解析式
海象运算符
什么时候不要使用解析式
注意嵌套的解析式
为大型数据集使用生成器
总结
首頁 後端開發 Python教學 Python列表解析式到底該怎麼用​​?

Python列表解析式到底該怎麼用​​?

Apr 16, 2023 pm 09:10 PM
python 程式設計語言 列表解析式

Python 是一種極其多樣化和強大的程式語言!當需要解決一個問題時,它有不同的方法。在本文中,將會展示列表解析式(List Comprehension)。我們將討論如何使用它?什麼時候該或不該使用它?

Python列表解析式到底該怎麼用​​?

列表解析式的優點

  • 比迴圈更節省時間和空間。
  • 需要更少的程式碼行。
  • 可將迭代語句轉換為公式。

如何在Python中建立清單

清單解析式是一種基於現有清單建立清單的語法結構。讓我們來看看創建列表的不同實作

循環

循環是創建列表的傳統方式。不管你使用什麼樣的循環。要以這種方式建立列表,您應該:

  1. 實例化一個空列表。
  2. 循環遍歷一個可迭代的(如range)的元素。
  3. 將每個元素附加到清單的末端。
numbers = []
for number in range(10):
numbers.append(number)

print(numbers)
登入後複製
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
登入後複製
登入後複製

在此範例中,您實例化了一個空列表 numbers。然後使用 for 循環迭代 range(10) 並使用 append() 方法將每個數字附加到清單的末端。

map() 物件

map() 是建立清單的另一種方法。您需要向 map() 傳遞一個函數和一個可迭代對象,之後它會建立一個物件。此物件包含使用指定函數執行每個迭代元素所獲得的輸出。

例如,我們將呈現在某些產品的價格中增加增值稅的任務。

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)
登入後複製

您已經建立了 add_vat() 函數並建立了 prices 可迭代物件。您將這兩個參數都傳遞給 map() 並收集產生的 map 物件 grand_prices,或者您可以使用 list() 輕鬆地將其轉換為清單。

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

列表解析式

現在,讓我們來看看列表解析式方法!這確實是 Python 風格,並且是建立清單的更好方法。為了弄清楚這種方法有多強大,我們用一個單行程式碼來重寫那個循環範例。

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

如您所見,這是一種不可思議的方法!清單解析式看起來足夠可讀,您不需要編寫更多程式碼,而只需一行。

為了更好地理解列表,請查看以下語法格式:

new_list = [expression for member in iterable]
登入後複製
登入後複製

哪種方法更有效

好的,我們已經學習瞭如何使用循環、map( ) 和列表解析式來建立列表,在您的腦海中可能會提出「哪種方法更有效」的問題。我們來分析一下吧!

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
登入後複製

正如我們現在所看到的,創建列表的最優的方法是 map(),排在第二位的是列表解析式,最後是循環。

但是,方法的選擇應取決於您想要實現的目標。

  • 使用map() 可以讓你的程式碼更有效率。
  • 使用循環可以讓程式碼的思路展現更加清晰。
  • 使用清單解析式可以您讓程式碼更加緊湊,且更有效率。這是建立清單的最佳方式,因為這種方式可讀性最強。

高級解析式

條件邏輯

早些時候,我向您展示了這個公式:

new_list = [expression for member in iterable]
登入後複製
登入後複製

公式可能有些不完整。對解析式的更完整描述增加了對可選條件的支援。將條件邏輯新增至清單解析式最常見的方法是在表達式的末端新增條件:

new_list = [expression for member in iterable (if conditional)]
登入後複製

在這裡,您的條件語句正好位於右邊的括號中。

條件很重要,因為它們允許列表解析式過濾掉不需要的值,這在一般情況下也可以呼叫 filter():

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

正如您所看到的那樣,這個解析式收集了可被2 整除且沒有餘數的數字。

如果您需要更複雜的篩選器,那麼您甚至可以將條件邏輯移到單獨的函數中。

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]
登入後複製

您建立 is_prime(number) 以確定是否是素數並傳回布林值。接下來,您應該將函數新增到解析式的條件中。

該公式可讓您使用條件邏輯從幾個可能的輸出選項中進行選擇。例如,您有一個產品價格表,若有負數,您應將其轉換為正數:

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]
登入後複製
登入後複製

在這裡,您的表達式 price 有一個條件語句,如果 price > 0 else price* -1。這會告訴 Python,如果價格為正,則輸出價格值;但如果價格為負,則將價格轉換為正值。該功能很強大,考慮將條件邏輯視為其自身的函數的確是很有用的:

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() 高效得多。

总结

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

現在你:

  • 學習了幾種創建清單的替代方法。
  • 找出每種方法的優點。
  • 可以簡化迴圈和 map() 呼叫列表解析式。
  • 了解一種將條件邏輯加入解析式中的方法。
  • 可以建立集合和字典解析式。
  • 學會了何時不使用解析式。

以上是Python列表解析式到底該怎麼用​​?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

PHP和Python:解釋了不同的範例 PHP和Python:解釋了不同的範例 Apr 18, 2025 am 12:26 AM

PHP主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。

在PHP和Python之間進行選擇:指南 在PHP和Python之間進行選擇:指南 Apr 18, 2025 am 12:24 AM

PHP適合網頁開發和快速原型開發,Python適用於數據科學和機器學習。 1.PHP用於動態網頁開發,語法簡單,適合快速開發。 2.Python語法簡潔,適用於多領域,庫生態系統強大。

為什麼要使用PHP?解釋的優點和好處 為什麼要使用PHP?解釋的優點和好處 Apr 16, 2025 am 12:16 AM

PHP的核心優勢包括易於學習、強大的web開發支持、豐富的庫和框架、高性能和可擴展性、跨平台兼容性以及成本效益高。 1)易於學習和使用,適合初學者;2)與web服務器集成好,支持多種數據庫;3)擁有如Laravel等強大框架;4)通過優化可實現高性能;5)支持多種操作系統;6)開源,降低開發成本。

PHP和Python:深入了解他們的歷史 PHP和Python:深入了解他們的歷史 Apr 18, 2025 am 12:25 AM

PHP起源於1994年,由RasmusLerdorf開發,最初用於跟踪網站訪問者,逐漸演變為服務器端腳本語言,廣泛應用於網頁開發。 Python由GuidovanRossum於1980年代末開發,1991年首次發布,強調代碼可讀性和簡潔性,適用於科學計算、數據分析等領域。

Python vs. JavaScript:學習曲線和易用性 Python vs. JavaScript:學習曲線和易用性 Apr 16, 2025 am 12:12 AM

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

PHP:服務器端腳本語言的簡介 PHP:服務器端腳本語言的簡介 Apr 16, 2025 am 12:18 AM

PHP是一種服務器端腳本語言,用於動態網頁開發和服務器端應用程序。 1.PHP是一種解釋型語言,無需編譯,適合快速開發。 2.PHP代碼嵌入HTML中,易於網頁開發。 3.PHP處理服務器端邏輯,生成HTML輸出,支持用戶交互和數據處理。 4.PHP可與數據庫交互,處理表單提交,執行服務器端任務。

sublime怎麼運行代碼python sublime怎麼運行代碼python Apr 16, 2025 am 08:48 AM

在 Sublime Text 中運行 Python 代碼,需先安裝 Python 插件,再創建 .py 文件並編寫代碼,最後按 Ctrl B 運行代碼,輸出會在控制台中顯示。

visual studio code 可以用於 python 嗎 visual studio code 可以用於 python 嗎 Apr 15, 2025 pm 08:18 PM

VS Code 可用於編寫 Python,並提供許多功能,使其成為開發 Python 應用程序的理想工具。它允許用戶:安裝 Python 擴展,以獲得代碼補全、語法高亮和調試等功能。使用調試器逐步跟踪代碼,查找和修復錯誤。集成 Git,進行版本控制。使用代碼格式化工具,保持代碼一致性。使用 Linting 工具,提前發現潛在問題。

See all articles