在 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),我們很難一眼看出 12 分別代表橫座標還是縱座標。

而命名元組則透過具名欄位來存取元素,就像一個輕量級的類別。以上述座標為例,我們可以定義一個 Point 命名元組,包含 xy 欄位:

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.xp2.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.xp2.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,並傳回一個閉包 multipliermultiplier 函式接收一個引數 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:widthheightarea。每個 property 都有一個 getter 方法,用於傳回相應例項變數的值。我們還為 widthheight 定義了 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:celsiusfahrenheitcelsius 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_radiusset_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() 方法來遍歷字典中的鍵值對,並使用多重指定來將鍵和值分別賦給 keyvalue 變數。這更簡潔、更易讀,並且更符合 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

上述程式碼使用三元運算元,將 xy 中較大的值賦給 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

這些範例展示瞭如何使用三元運算元,讓程式碼更簡潔易讀。