Python 入門 (4) - 函數

Python 函數:

在Python中,函數(function)是一組可重複使用的程式碼塊,它接受一個或多個輸入(參數),並根據輸入執行某些操作。

函數能夠讓程式更加模塊化,使程式碼更易於理解、重用和維護。

本文流程:

初級函數用法:

1. 定義無回傳值的函數:

使用 def 關鍵字來定義函數,後接函數名稱 (greet)和括號,括號內是參數(name),然後是冒號和函數主體。

# 定義 greet 函數
def greet(name):
    print(f"Hello, {name}!")

# 呼叫 greet 函數
greet("Ben")

我們可以利用 """說明文字""" 的方式幫函數添加說明 (docstring) 來增加程式的可讀性

Docstring 中可以描述函數的功能、參數和返回值 (後續詳述)。

def greet(name):
    """
    This function greets the user.
    
    :param name: The name of the person to greet.
    :return: None
    """
    print(f"Hello, {name}!")

2. 定義有回傳值的函數:

利用 return 我們可以將函數計算的結果進行回傳並賦值給其他變數:

def add_numbers(a, b):
    """
    This function adds two numbers and returns the result.
    
    :param a: The first number.
    :param b: The second number.
    :return: The sum of the two numbers.
    """
    return a + b

# 將計算的結果存在 result
result = add_numbers(10, 20)

# 也可以選擇不接收
add_numbers(3.77, 600)

3. 定義多重回傳值的函數:

在 Python 中允許以 tuple 的方式一次回傳多個值:

def sum_and_product(a, b):
    """
    This function calculates the sum and product of two numbers.
    
    :param a: The first number.
    :param b: The second number.
    :return: A tuple containing the sum and product of the two numbers.
    """
    sum_result = a + b
    product_result = a * b
    return sum_result, product_result

# 將計算的結果存在對應的變數中
sum_result, product_result = sum_and_product(10, 20)

# '_' 是用來標示該計算結果可以被忽略 
# 但 '_' 也是一個變數 
_, product_result = sum_and_product(10, 20)
sum_result, _ = sum_and_product(10, 20)
print(f"The value of {_}")

# 將兩個結果存在 all_results 這個 tuple 中
all_results = sum_and_product(10, 20)
print(f"The sum is: {all_results[0]}, the product is {all_results[1]}")

4. 透過參數的名稱呼叫函數:

透過參數的名稱呼叫函數是一種更具可讀性的方法,你可以通過指定參數名稱來給函數傳遞參數值,而不必依賴於它們的位置

def greet(greeting, name):
    """
    This function greets the user.

    :param greeting: The greeting.
    :param name: The name of the person to greet.
    :return: None
    """
    print(f"{greeting}, {name}!")

# 預設第一個參數是 greeting, 預設第二個參數是 name
greet("Hello", "Ben")

# 適當的加入參數的名字可以增加可讀性
greet(greeting="Hello", name="Ben")

# 參數具名時可以改變順序
greet(name="Ben", greeting="Hello")

5. 函數參數的預設值:

透過參數的名稱呼叫函數是一種更具可讀性的方法,你可以通過指定參數名稱來給函數傳遞參數值,而不必依賴於它們的位置

def greet(name, greeting="Hello"):
    """
    This function greets the user.

    :param name: The name of the person to greet.
    :param greeting: The greeting.
    :return: None
    """
    print(f"{greeting}, {name}!")

# 呼叫時沒有設定 greeting 預設為 'Hello'
greet("Ben")

進階函數用法:

6. 不定數量參數的 tuple:

*args 用於接受不定數量的參數,並將它們收集為一個元組 (tuple)

def my_sum(*args):
    """
    This function prints each positional argument passed to it.

    :param args: A variable-length list of positional arguments.
    :return: The sum of arguments.
    """
    total = 0
    
    # 使用 for-in 來走訪 tuple
    for arg in args:
        total += arg
    return total

# 傳入不定數量的參數
result = my_sum()
print(f"result: {result}")

result = my_sum(10)
print(f"result: {result}")

result = my_sum(10, 20)
print(f"result: {result}")

result = my_sum(10, 20, 30)
print(f"result: {result}")

7. 不定數量參數的 dict:

**kwargs用於接受不定數量的關鍵字參數,它將它們收集為一個字典

def my_function(**kwargs):
    for key, value in kwargs.items():
        print(key, ":", value)

my_function(name="Alice", age=30, city="New York")

高級函數用法:

8. lambda 函數:

lambda 函數是一種在一行中定義的短匿名函數。它可以接受任意數量的參數,但只能有一個表達式,該表達式的結果將成為該函數的返回值。

lambda arguments: expression

一般函數的寫法:

def add(x,y):
    return x + y

lambda 函數的寫法:

# 定義 add 是一個 lambda 函數
# 該函數接收 x, y 並將 x + y 的結果回傳
add = lambda x, y: x + y

print(add(3, 5))  # Output: 8

9. lambda 函數的使用場景:

先來看一個例子,假設我們想定義一個 my_filter 函數它可以從 numbers 中過濾出所有大於 5 的數並存在 list 中:

def my_filter(numbers):
    result = []
    for num in numbers:
        if num > 5:
            result.append(num)
    return result

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

透過 lambda 函數,搭配 filter 函數我們可以將程式碼變得更為簡潔。

下例中 fileter() 會走訪 numbers 中的所有元素並帶入 lambda 函數,lambda 函數回傳 True 的元素才會被 fileter() 留下:

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# 從 numbers 中過濾出 > 5 的數,並存成 list
filtered_result = list(filter(lambda x: x > 5, numbers))
print(filtered_result) # [6, 7, 8, 9, 10]

lambda 函數也常搭配 map() 跟 sorted() 等函數一起使用。

下例中 map() 會走訪 numbers 中的所有元素並帶入 lambda 函數,lambda 函數會回傳元素平方的值:

numbers = [1, 2, 3, 4, 5]

# 從 numbers 取出元素當成 x,計算 x * x 並回傳
squared_numbers = list(map(lambda x: x * x, numbers))
print(squared_numbers)  # Output: [1, 4, 9, 16, 25]

sorted() 中的 key 參數被用來決定如何進行資料的排序。

下例中 sorted() 會走訪 students 中的所有元素並帶入 lambda 函數並將其設定為 tuple x,其中 x[0] 為姓名 x[1] 為年齡:

students = [('Alice', 23), ('Bob', 20), ('Charlie', 25), ('David', 22)]

# 按 tuple 的索引 0 即名字排序,預設是 A 到 Z  
sorted_students_by_name = sorted(students, key=lambda x: x[0])
print(sorted_students_by_name)  # Output: ('Alice', 23), ('Bob', 20), ('Charlie', 25), ('David', 22)]

# 按 tuple 的索引 1 即年齡排序,預設是小到大 
sorted_students_by_age = sorted(students, key=lambda x: x[1])
print(sorted_students_by_age)  # Output: [('Bob', 20), ('David', 22), ('Alice', 23), ('Charlie', 25)]

# 按 tuple 的索引 1 即年齡反向排序 
reverse_sorted_students_by_age = sorted(students, key=lambda x: x[1], reverse=True)
print(reverse_sorted_students_by_age)  # Output: [('Charlie', 25), ('Alice', 23), ('David', 22), ('Bob', 20)]

留言

熱門文章