在 Python 開發中,提升程式碼的可讀性和可維護性至關重要。魔術數字和字串的存在會降低程式碼的清晰度,增加維護的難度。本文將探討如何有效地消除這些魔術數字和字串,並提供一些最佳實務和技巧。透過使用常數、命名變數、列舉以及組態檔案,我們可以讓程式碼更具表達力,更容易理解和修改。舉例來說,將程式碼中重複出現的數字 7 指定給一個名為 DAYS_IN_WEEK 的常數,可以清楚地表達這個數字的含義。同樣地,使用描述性的變數名稱代替硬編碼的字串,也能提高程式碼的可讀性。此外,列舉型別可以更有效地管理一組相關的常數,例如星期幾或月份。最後,組態檔案可以將程式碼中需要頻繁修改的值外部化,提高程式碼的靈活性。
擺脫魔術:Python 程式碼的清晰之道
在程式碼中,魔術數字和字串是指那些沒有明確含義的硬編碼值。它們會降低程式碼的可讀性和可維護性,並增加錯誤的風險。
1. 常數的魅力:定義明確的值
使用常數來代替硬編碼值,可以提高程式碼的可讀性和可維護性。例如:
# 定義一週的天數
DAYS_IN_WEEK = 7
# 使用常數代替硬編碼值
for i in range(DAYS_IN_WEEK):
...
2. 命名變數:賦予字串意義
使用命名變數來代替硬編碼字串,可以提高程式碼的可讀性和可維護性。例如:
# 定義欄位名稱
NAME_COLUMN = "name"
AGE_COLUMN = "age"
# 使用變數代替硬編碼字串
if column == NAME_COLUMN:
...
3. 列舉的妙用:限定選項範圍
列舉 (Enum) 是一種特殊的常數,用於表示一組固定的值。它們可以提高程式碼的可讀性和可維護性。例如:
from enum import Enum
# 定義一週的每一天
class Weekday(Enum):
MONDAY = 1
TUESDAY = 2
WEDNESDAY = 3
THURSDAY = 4
FRIDAY = 5
SATURDAY = 6
SUNDAY = 7
# 使用列舉代替硬編碼值
day = Weekday.MONDAY
if day == Weekday.SATURDAY:
...
4. 組態檔案:靈活的值管理
使用組態檔案來儲存程式碼中的值,可以提高程式碼的靈活性和可組態性。例如:
import configparser
config = configparser.ConfigParser()
config.read("config.ini")
# 在程式碼中使用組態值
if config.getboolean("debug", "enabled"):
...
避免魔術數字和字串是編寫可讀與易於維護的 Python 程式碼的重要一環。透過定義常數、使用命名變數、使用列舉以及使用組態檔案,可以讓程式碼更清晰、更靈活。
玄貓認為,編寫高品質的程式碼不僅僅是讓程式能夠執行,更重要的是讓程式碼易於理解、易於維護。好的命名和避免魔術數字是實作這一目標的關鍵步驟。
Pythonic 的精髓:如何寫出更優雅的程式碼
Python 以其簡潔和可讀性著稱,但要真正掌握 Pythonic 的程式碼風格,需要深入理解其內建功能和語法特性。玄貓(BlackCat)將分享如何運用列表生成式、生成器表示式、內建函式以及 with 陳述式,讓你的程式碼更簡潔、更易讀,同時兼顧效能。
列表生成式與生成器表示式:簡潔高效的資料處理
列表生成式(List Comprehension)和生成器表示式(Generator Expression)是 Python 中建立列表和生成器的強大工具。它們能以簡潔的語法,從現有序列中產生新的序列。
例如,將一個數字列表中的每個元素平方:
numbers = [1, 2, 3, 4, 5]
squares = [x ** 2 for x in numbers] # 使用列表生成式
# 內容解密:這行程式碼會迭代 numbers 列表,將每個元素 x 平方後,放入一個新的列表 squares 中。
print(squares) # 輸出:[1, 4, 9, 16, 25]
若要處理大型資料集,生成器表示式更具優勢,因為它不會一次性將所有元素載入記憶體:
numbers = [1, 2, 3, 4, 5]
squares = (x ** 2 for x in numbers) # 使用生成器表示式
# 內容解密:與列表生成式不同,生成器表示式產生的是一個生成器物件,只有在迭代時才會逐一產生元素。
for square in squares:
print(square)
# 輸出:
# 1
# 4
# 9
# 16
# 25
列表生成式還支援巢狀結構,可以處理更複雜的資料轉換。例如,建立一個 3x3 的零矩陣:
rows = 3
cols = 3
matrix = [[0 for j in range(cols)] for i in range(rows)]
# 內容解密:外層迴圈迭代行,內層迴圈迭代列,產生一個二維列表,每個元素都是 0。
print(matrix) # 輸出:[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
善用內建函式:告別迴圈的冗長
Python 提供了許多強大的內建函式,可以簡化常見的資料處理任務。map()、filter()、reduce()、zip() 和 enumerate() 是其中幾個特別有用的函式。
-
map(): 將函式應用於序列中的每個元素,並傳回一個包含結果的新序列。numbers = [1, 2, 3, 4, 5] squared = list(map(lambda x: x**2, numbers)) # 內容解密:lambda 函式定義了一個匿名函式,將輸入 x 平方。map() 函式將此匿名函式應用於 numbers 列表的每個元素。 print(squared) # 輸出:[1, 4, 9, 16, 25] -
filter(): 根據指定條件過濾序列中的元素,並傳回一個包含符合條件元素的新序列。numbers = [1, 2, 3, 4, 5] even_numbers = list(filter(lambda x: x % 2 == 0, numbers)) # 內容解密:lambda 函式定義了一個匿名函式,檢查輸入 x 是否為偶數。filter() 函式將此匿名函式應用於 numbers 列表的每個元素,只保留偶數。 print(even_numbers) # 輸出:[2, 4] -
reduce(): 將序列中的元素累積應用於一個函式,最終傳回單一結果。from functools import reduce numbers = [1, 2, 3, 4, 5] total = reduce(lambda x, y: x + y, numbers) # 內容解密:lambda 函式定義了一個匿名函式,將兩個輸入 x 和 y 相加。reduce() 函式將此匿名函式應用於 numbers 列表的前兩個元素,然後將結果與下一個元素相加,以此類別推,直到所有元素都被處理。 print(total) # 輸出:15 -
zip(): 將多個序列中對應位置的元素封裝成元組,並傳回一個包含這些元組的新序列。names = ["Alice", "Bob", "Charlie"] ages = [25, 30, 35] people = list(zip(names, ages)) # 內容解密:zip() 函式將 names 列表和 ages 列表中對應位置的元素封裝成元組。 print(people) # 輸出:[('Alice', 25), ('Bob', 30), ('Charlie', 35)] -
enumerate(): 將序列中的元素及其索引封裝成元組,並傳回一個包含這些元組的新序列。fruits = ["apple", "banana", "orange"] for index, fruit in enumerate(fruits): print(f"{index}: {fruit}") # 內容解密:enumerate() 函式將 fruits 列表中的每個元素及其索引封裝成元組。 # 輸出: # 0: apple # 1: banana # 2: orange
with 陳述式:優雅的資源管理
with 陳述式提供了一種簡潔的方式來管理資源,例如檔案、資料函式庫連線和網路連線。它可以確保資源在使用完畢後被正確釋放,即使發生異常也不例外。
以下是一個使用 with 陳述式開啟檔案並讀取內容的範例:
with open('example.txt', 'r') as file:
contents = file.read()
# 內容解密:with 陳述式確保檔案在使用完畢後會被自動關閉,即使在讀取檔案的過程中發生異常。
print(contents)
with 陳述式也可以用於管理資料函式庫連線:
import sqlite3
with sqlite3.connect('example.db') as conn:
cursor = conn.cursor()
cursor.execute('SELECT * FROM customers')
# 內容解密:with 陳述式確保資料函式庫連線在使用完畢後會被自動關閉,即使在執行查詢的過程中發生異常。
玄貓(BlackCat)認為,掌握這些 Pythonic 的技巧,能讓你寫出更簡潔、更易讀、更有效率的程式碼,提升開發效率和程式碼品質。
命名元組的妙用:提升 Python 程式碼的可讀性
在 Python 的世界裡,命名元組(named tuple)是一種輕量級的資料結構,它繼承了元組的不可變特性,同時又賦予了每個元素名稱,讓程式碼更易讀、更具自我描述性。
告別索引:擁抱具名欄位
傳統的元組透過索引來存取元素,當元素數量一多,程式碼的可讀性就會大打折扣。例如,一個表示座標的元組 (1, 2),我們很難一眼看出 1 和 2 分別代表橫座標還是縱座標。
而命名元組則透過具名欄位來存取元素,就像一個輕量級的類別。以上述座標為例,我們可以定義一個 Point 命名元組,包含 x 和 y 欄位:
from collections import namedtuple
# 定義一個名為 'Point' 的命名元組,包含 'x' 和 'y' 兩個欄位
Point = namedtuple('Point', ['x', 'y'])
# 建立兩個點
p1 = Point(x=1, y=2)
p2 = Point(x=4, y=6)
# 存取點的座標
print(p1.x) # 輸出: 1
print(p2.y) # 輸出: 6
透過 p1.x 和 p2.y,我們可以清楚地知道存取的是橫座標和縱座標,程式碼的可讀性大幅提升。
實戰範例:計算兩點之間的距離
命名元組不僅能提升可讀性,還能讓程式碼更易於維護。以下是一個計算兩點之間距離的範例:
from collections import namedtuple
import math
# 定義一個名為 'Point' 的命名元組,包含 'x' 和 'y' 兩個欄位
Point = namedtuple('Point', ['x', 'y'])
# 定義一個函式,計算兩點之間的距離
def distance(p1, p2):
dx = p1.x - p2.x
dy = p1.y - p2.y
return math.sqrt(dx**2 + dy**2)
# 建立兩個點
p1 = Point(x=1, y=2)
p2 = Point(x=4, y=6)
# 計算兩點之間的距離
d = distance(p1, p2)
print(f"The distance between {p1} and {p2} is {d:.2f}.")
在這個範例中,distance 函式接收兩個 Point 物件作為引數,並使用畢氏定理計算它們之間的距離。透過命名元組,我們可以清楚地知道 p1.x 和 p2.y 代表什麼,程式碼的意圖一目瞭然。
玄貓認為,命名元組是 Python 中一個強大與實用的特性,它可以大幅提升程式碼的可讀性和組織性。透過使用命名元組,開發者可以建立輕量級、具自我描述性的物件,讓程式碼更易讀、更不易出錯。
活用閉包:提升 Python 程式碼的模組化與重用性
在 Python 的函式式程式設計中,閉包(closure)是一個強大的工具,它允許函式存取並操作外層作用域的變數,即使在外層函式已經傳回後,閉包仍然能夠記住這些變數的值。
閉包的奧秘:記住外層作用域
閉包的本質是一個函式,它保留了對外層函式作用域的參照。這意味著,即使外層函式已經執行完畢,閉包仍然可以存取外層函式的變數。
以下是一個簡單的閉包範例:
def outer_function(x):
def inner_function(y):
return x + y
return inner_function
# 建立一個閉包,將外層函式的 x 設定為 10
closure = outer_function(10)
# 呼叫閉包,傳入引數 y = 5
result = closure(5)
print(result) # 輸出: 15
在這個範例中,inner_function 是一個閉包,它記住了外層函式 outer_function 的變數 x。即使 outer_function 已經傳回,closure 仍然可以存取 x 的值。
實戰範例:建立乘法器
閉包可以被用來建立各種各樣的函式,例如乘法器。以下是一個建立乘法器的範例:
def make_multiplier(x):
def multiplier(y):
return x * y
return multiplier
# 建立兩個閉包,一個將輸入乘以 2,另一個將輸入乘以 3
double = make_multiplier(2)
triple = make_multiplier(3)
# 使用閉包來乘以一些數字
print(double(5)) # 輸出: 10
print(triple(5)) # 輸出: 15
在這個範例中,make_multiplier 函式接收一個引數 x,並傳回一個閉包 multiplier。multiplier 函式接收一個引數 y,並傳回 x * y 的結果。透過 make_multiplier 函式,我們可以輕鬆地建立各種不同的乘法器。
玄貓認為,閉包是 Python 中一個強大與靈活的特性,它可以被用來建立可重用、模組化的程式碼。透過使用閉包,開發者可以將程式碼分解成更小的、更易於管理的部分,從而提高程式碼的可讀性和可維護性。
善用 Properties:最佳化 Python 程式碼的可讀性與可維護性
在 Python 中,properties 是一種特殊的屬性,它允許開發者定義類別似於簡單屬性的方法,同時又能提供方法的完整功能。Properties 可以用於驗證或清理輸入、計算衍生值,或觸發副作用,同時為存取和修改物件狀態提供清晰直觀的介面。
Properties 的優雅:兼顧簡潔與功能
Properties 的主要優點在於,它們允許開發者在不改變類別介面的情況下,控制屬性的存取和修改。這使得程式碼更易於閱讀和維護,同時又能提供額外的功能。
以下是一個簡單的 property 範例:
class Rectangle:
def __init__(self, width, height):
self._width = width
self._height = height
@property
def width(self):
return self._width
@width.setter
def width(self, value):
if value <= 0:
raise ValueError("Width must be positive")
self._width = value
@property
def height(self):
return self._height
@height.setter
def height(self, value):
if value <= 0:
raise ValueError("Height must be positive")
self._height = value
@property
def area(self):
return self._width * self._height
在這個範例中,Rectangle 類別有兩個私有例項變數 _width 和 _height。我們使用 @property 裝飾器定義了三個 properties:width、height 和 area。每個 property 都有一個 getter 方法,用於傳回相應例項變數的值。我們還為 width 和 height 定義了 setter 方法,用於驗證新值是否為正數。最後,我們定義了一個 area property,用於計算矩形的面積。
實戰範例:溫度轉換器
Properties 可以被用來建立各種各樣的類別,例如溫度轉換器。以下是一個建立溫度轉換器的範例:
class Temperature:
def __init__(self, celsius):
self._celsius = celsius
@property
def celsius(self):
return self._celsius
@celsius.setter
def celsius(self, value):
if value < -273.15:
raise ValueError("Temperature cannot be below absolute zero")
self._celsius = value
@property
def fahrenheit(self):
return self._celsius * 9 / 5 + 32
@fahrenheit.setter
def fahrenheit(self, value):
self._celsius = (value - 32) * 5 / 9
在這個範例中,Temperature 類別有一個私有例項變數 _celsius。我們使用 @property 裝飾器定義了兩個 properties:celsius 和 fahrenheit。celsius property 有一個 getter 方法,用於傳回 _celsius 的值,以及一個 setter 方法,用於驗證新值是否不低於絕對零度(-273.15 攝氏度)。fahrenheit property 有一個 getter 方法,用於計算當前攝氏溫度的華氏溫度,以及一個 setter 方法,用於根據華氏輸入設定攝氏溫度。
玄貓認為,properties 是 Python 中一個實用與強大的特性,它可以被用來提高程式碼的可讀性和可維護性。透過定義類別似於簡單屬性的方法,開發者可以為存取和修改物件狀態提供清晰直觀的介面,同時又能提供額外的功能。
總之,Python 提供了許多強大的特性,例如命名元組、閉包和 properties,這些特性可以幫助開發者編寫更易讀、更易維護、更模組化的程式碼。掌握這些特性,可以讓你的 Python 程式碼更上一層樓。
屬性(Properties):Pythonic 的優雅之道
在 Python 中,屬性提供了一種優雅的方式來管理類別的屬性存取。它們允許你定義方法來處理屬性的讀取、設定和刪除,同時保持像直接存取屬性一樣的簡潔語法。這種方式不僅提高了程式碼的可讀性,還允許你在屬性存取時執行驗證或其他操作。
舉例來說,假設我們有一個 Circle 類別,我們希望確保半徑(radius)永遠是正數:
class Circle:
def __init__(self, radius):
self._radius = radius # 使用底線表示這是一個 "受保護的" 屬性
def get_radius(self):
return self._radius
def set_radius(self, value):
if value <= 0:
raise ValueError("Radius must be positive")
self._radius = value
radius = property(get_radius, set_radius)
# 範例
circle = Circle(5)
print(circle.radius) # 輸出: 5
circle.radius = 10
print(circle.radius) # 輸出: 10
try:
circle.radius = -1
except ValueError as e:
print(e) # 輸出: Radius must be positive
在這個例子中,property() 函式將 get_radius 和 set_radius 方法繫結到 radius 屬性。現在,當我們存取 circle.radius 時,實際上是在呼叫 get_radius() 方法;當我們設定 circle.radius 時,實際上是在呼叫 set_radius() 方法。
Python 的 @property 裝飾器提供了一種更簡潔的語法來定義屬性:
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
return self._radius
@radius.setter
def radius(self, value):
if value <= 0:
raise ValueError("Radius must be positive")
self._radius = value
# 範例
circle = Circle(5)
print(circle.radius)
circle.radius = 10
print(circle.radius)
try:
circle.radius = -1
except ValueError as e:
print(e)
這段程式碼的功能與前一個例子完全相同,但使用了更簡潔的 @property 裝飾器。這種方式更易於閱讀和理解,是 Python 開發者常用的技巧。
內容解密
property()函式或@property裝飾器:用於將方法轉換為屬性,允許在屬性存取時執行額外的邏輯。getter方法:用於取得屬性的值。setter方法:用於設定屬性的值,並可包含驗證邏輯。@property裝飾器:提供了一種更簡潔的語法來定義屬性。
描述器(Descriptors):屬性存取的幕後推手
Python 描述器是一種更底層的機制,用於控制屬性的存取。它們允許你建立行為類別似變數的物件,但在存取或指定時具有自訂的行為。描述器是實作屬性(properties)的基礎,但它們的功能遠不止於此。
一個描述器是一個物件,它定義了 __get__()、__set__() 或 __delete__() 方法中的至少一個。當一個描述器被用作類別屬性時,這些方法會在屬性被存取、指定或刪除時被呼叫。
以下是一個簡單的描述器範例:
class Value:
def __get__(self, instance, owner):
print("Getting value")
return instance._value
def __set__(self, instance, value):
print("Setting value to", value)
instance._value = value
class MyClass:
x = Value() # x 是一個描述器
def __init__(self, value):
self._value = value
# 範例
my_object = MyClass(10)
print(my_object.x) # 輸出: Getting value \n 10
my_object.x = 20 # 輸出: Setting value to 20
print(my_object.x) # 輸出: Getting value \n 20
在這個例子中,Value 類別是一個描述器。當我們存取 my_object.x 時,Value 類別的 __get__() 方法被呼叫;當我們設定 my_object.x 時,__set__() 方法被呼叫。
描述器的一個常見用途是實作驗證邏輯。例如,我們可以建立一個 PositiveNumber 描述器,它確保屬性值永遠是正數:
class PositiveNumber:
def __get__(self, instance, owner):
return instance._value
def __set__(self, instance, value):
if value <= 0:
raise ValueError("Value must be positive")
instance._value = value
class MyClass:
x = PositiveNumber()
def __init__(self, x):
self.x = x
# 範例
try:
my_object = MyClass(-1)
except ValueError as e:
print(e) # 輸出: Value must be positive
my_object = MyClass(10)
print(my_object.x) # 輸出: 10
描述器提供了一種強大的方式來自訂屬性的行為。它們可以用於實作驗證、延遲載入、快取和其他進階功能。
內容解密
__get__(self, instance, owner): 在屬性被存取時呼叫。__set__(self, instance, value): 在屬性被指定時呼叫。__delete__(self, instance): 在屬性被刪除時呼叫。- 描述器可以用於實作驗證、延遲載入、快取和其他進階功能。
元類別(Metaclasses):控制類別的創造
在 Python 中,類別本身也是物件,它們是元類別的例項。元類別是「類別的類別」,它們控制著類別的建立過程。透過使用元類別,你可以自訂類別的建立方式、修改類別屬性,以及執行其他進階操作。
一個簡單的元類別範例:
class MyMeta(type):
def __new__(cls, name, bases, attrs):
print("Creating class:", name)
return super().__new__(cls, name, bases, attrs)
class MyClass(metaclass=MyMeta):
pass
# 輸出: Creating class: MyClass
在這個例子中,MyMeta 是一個元類別,它繼承自 type。__new__() 方法在類別被建立時呼叫。透過覆寫 __new__() 方法,我們可以自訂類別的建立過程。
元類別的一個常見用途是自動增加屬性到類別中:
class MyMeta(type):
def __new__(cls, name, bases, attrs):
attrs['my_attribute'] = 42
return super().__new__(cls, name, bases, attrs)
class MyClass(metaclass=MyMeta):
pass
print(MyClass.my_attribute) # 輸出: 42
在這個例子中,MyMeta 元類別在 MyClass 類別中增加了一個名為 my_attribute 的屬性,並將其值設定為 42。
元類別提供了一種強大的方式來自訂類別的行為。它們可以用於實作單例模式、自動註冊類別、驗證類別結構和其他進階功能。
內容解密
- 元類別是「類別的類別」,它們控制著類別的建立過程。
__new__(cls, name, bases, attrs): 在類別被建立時呼叫。- 元類別可以用於自訂類別的建立方式、修改類別屬性,以及執行其他進階操作。
編寫 Pythonic 迴圈:簡潔、易讀的 Python 風格
Python 以其可讀性和簡潔性而聞名。編寫 Pythonic 程式碼意味著利用 Python 的特性來編寫清晰、簡潔與易於理解的程式碼。在迴圈方面,Python 提供了許多方法來簡化程式碼並使其更具可讀性。
迴圈遍歷列表:
在 Python 中,最常見的迴圈場景之一是遍歷列表。以下是一個非 Pythonic 的範例:
my_list = [1, 2, 3, 4, 5]
for i in range(len(my_list)):
print(my_list[i])
這個程式碼使用 range() 函式生成一個索引序列,然後使用索引來存取列表中的每個專案。雖然這段程式碼可以工作,但它不是 Pythonic 的。更 Pythonic 的方法是直接遍歷列表中的專案:
my_list = [1, 2, 3, 4, 5]
for item in my_list:
print(item)
這個程式碼直接遍歷列表中的專案,而無需使用索引。這更簡潔、更易讀,並且更符合 Python 的風格。
迴圈遍歷字典:
另一個常見的迴圈場景是遍歷字典。以下是一個非 Pythonic 的範例:
my_dict = {'a': 1, 'b': 2, 'c': 3}
for key in my_dict:
value = my_dict[key]
print(key, value)
這個程式碼遍歷字典中的鍵,然後使用鍵來存取對應的值。雖然這段程式碼可以工作,但它不是 Pythonic 的。更 Pythonic 的方法是使用 items() 方法來遍歷字典中的鍵值對:
my_dict = {'a': 1, 'b': 2, 'c': 3}
for key, value in my_dict.items():
print(key, value)
這個程式碼使用 items() 方法來遍歷字典中的鍵值對,並使用多重指定來將鍵和值分別賦給 key 和 value 變數。這更簡潔、更易讀,並且更符合 Python 的風格。
內容解密
- 直接遍歷列表中的專案,而不是使用索引。
- 使用
items()方法來遍歷字典中的鍵值對。 - 使用多重指定來簡化程式碼。
總之,編寫 Pythonic 程式碼意味著利用 Python 的特性來編寫清晰、簡潔與易於理解的程式碼。透過遵循這些最佳實務,你可以編寫更 Pythonic 的迴圈,並提高程式碼的可讀性和可維護性。
在本文中,玄貓探討了 Python 中一些進階特性,包括屬性、描述器、元類別和 Pythonic 迴圈。這些特性可以幫助你編寫更簡潔、更易讀與更具可維護性的程式碼。
Python 迴圈技巧:提升程式碼效率與可讀性
在 Python 中,迴圈是程式設計中不可或缺的一環。掌握更有效率、更 Pythonic 的迴圈技巧,能大幅提升程式碼的可讀性與執行效率。玄貓將分享一些 Python 迴圈的進階用法,並透過實際案例說明。
字典迭代的 Pythonic 風格
傳統上,我們可能會這樣迭代字典:
my_dict = {'a': 1, 'b': 2, 'c': 3}
for key in my_dict:
print(key, my_dict[key])
但更簡潔、更 Pythonic 的方式是使用 items() 方法:
my_dict = {'a': 1, 'b': 2, 'c': 3}
for key, value in my_dict.items():
print(key, value)
items() 方法直接傳回鍵值對的迭代器,讓程式碼更簡潔易懂。
條件式迴圈:更優雅的寫法
當需要在迴圈中根據條件處理元素時,傳統寫法可能如下:
my_list = [1, 2, 3, 4, 5]
for i in range(len(my_list)):
if my_list[i] > 2:
print(my_list[i])
更 Pythonic 的做法是直接迭代列表元素:
my_list = [1, 2, 3, 4, 5]
for item in my_list:
if item > 2:
print(item)
這樣不僅程式碼更簡潔,也避免了使用索引可能產生的錯誤。
enumerate() 與 zip() 的妙用
Python 內建的 enumerate() 和 zip() 函式,能讓迴圈操作更強大。
enumerate():追蹤索引
enumerate() 函式可以在迭代序列的同時,追蹤當前元素的索引。這在需要同時使用元素及其索引時非常方便。
my_list = ['apple', 'banana', 'orange']
for i, item in enumerate(my_list):
print(i, item)
zip():同時迭代多個序列
zip() 函式可以同時迭代多個序列,將它們對應的元素組合成元組。
list_a = [1, 2, 3]
list_b = ['a', 'b', 'c']
for item_a, item_b in zip(list_a, list_b):
print(item_a, item_b)
enumerate()與zip()結合
更進階的用法是將 enumerate() 和 zip() 結合,同時迭代序列及其索引。
my_list = ['apple', 'banana', 'orange']
for i, (item, index) in enumerate(zip(my_list, range(len(my_list)))):
print(i, item, index)
這種寫法避免了使用 range() 產生索引序列,程式碼更簡潔。
三元運算元:簡化條件表示式
三元運算元 (ternary operator) 是一種簡潔的條件表示式寫法,可以替代簡單的 if-else 陳述式。
- 基本語法
<expression_if_true> if <condition> else <expression_if_false>
- 使用案例
x = 10
y = 20
max_num = x if x > y else y
上述程式碼使用三元運算元,將 x 和 y 中較大的值賦給 max_num 變數。
- Pythonic 風格
在 Python 中,應以易讀易懂的方式使用三元運算元。以下是一些 Pythonic 的範例:
# 檢查值是否在列表中
my_list = [1, 2, 3, 4, 5]
index = my_list.index(6) if 6 in my_list else -1
# 設定預設值
my_var = None
my_var = my_var if my_var is not None else "default_value"
# 檢查變數是否為空
my_var = ""
is_empty = True if len(my_var) == 0 else False
這些範例展示瞭如何使用三元運算元,讓程式碼更簡潔易讀。