返回文章列表

Python資料結構變數型別與字典操作

本文深入探討 Python 的變數與資料型別,包含列表、元組、字典等核心概念,並解析函式引數傳遞機制與應用,同時示範矩陣螢幕保護程式與二進位制樹狀圖的程式碼實作,最後提供練習題與解答,幫助讀者強化 Python 基礎知識。

Python 程式設計

Python 的變數實質上是指向資料的參考,而非資料本身。理解變數的參考特性對於操作可變資料型別,例如列表和字典,至關重要。當多個變數指向同一個可變物件時,修改其中一個變數會影響所有指向該物件的變數。這與不可變資料型別(如整數、字串、元組)不同,修改不可變資料型別會建立新的物件,而不會影響其他變數。函式引數傳遞也遵循此原則,傳遞可變物件相當於傳遞參考,函式內部的修改會直接影響原始物件。為避免此情況,可以使用 copy()deepcopy() 建立副本。列表和字典的常用操作包括索引、切片、新增、刪除等。字典使用鍵值對儲存資料,提供高效的資料查詢和組織方式。

變數與資料型別

在 Python 中,變數可以被視為貼在值上的標籤。當你將一個值賦給變數時,你實際上是在記憶體中建立了該值,並將變數作為對該值的參照。這意味著變數本身並不包含值,而是包含對值的參照。

資料型別轉換

Python 提供了多種資料型別,包括整數、浮點數、字串、列表、元組等。每種資料型別都有其特定的用途和行為。例如,整數和浮點數用於數字運算,而字串用於文書處理。

你可以使用 list()tuple() 函式將其他資料型別轉換為列表或元組。例如:

>>> tuple(['cat', 'dog', 5])
('cat', 'dog', 5)
>>> list(('cat', 'dog', 5))
['cat', 'dog', 5]
>>> list('hello')
['h', 'e', 'l', 'l', 'o']

這些轉換可以幫助你在不同資料型別之間進行操作。

變數參照

當你將一個變數賦給另一個變數時,你實際上是在複製參照,而不是複製值。這意味著兩個變數都指向相同的值。例如:

>>> spam = 42
>>> eggs = spam
>>> spam = 99
>>> spam
99
>>> eggs
42

在這個例子中,eggs 變數仍然指向原始的 42 值,而 spam 變數已經被重新指定為 99

列表與可變性

列表是一種特殊的資料型別,它可以被修改。當你將一個列表賦給另一個變數時,你實際上是在複製參照,而不是複製列表本身。這意味著兩個變數都指向相同的列表。例如:

>>> spam = [0, 1, 2, 3]
>>> eggs = spam
>>> eggs[1] = 'Hello!'
>>> spam
[0, 'Hello!', 2, 3]
>>> eggs
[0, 'Hello!', 2, 3]

在這個例子中,eggs 變數修改了列表的第二個元素,這也影響了 spam 變數所指向的列表。

瞭解函式引數傳遞的機制

當函式被呼叫時,Python會將引數的參考複製到引數變數中。對於可變值,如列表(和字典),這意味著函式中的程式碼會直接修改原始值。讓我們來看看下面的例子:

def eggs(some_parameter):
    some_parameter.append('Hello')

spam = [1, 2, 3]
eggs(spam)
print(spam)  # 輸出:[1, 2, 3, 'Hello']

在這個例子中,當我們呼叫eggs()函式時,some_parameter引數會指向同一個列表物件,如spam。因此,當我們在函式中呼叫append('Hello')方法時,原始列表會被修改。

使用copy()deepcopy()函式

雖然傳遞參考通常是處理列表和字典的最方便方式,但如果函式修改了傳遞給它的列表或字典,您可能不希望這些修改影響原始值。為了控制這種行為,Python提供了一個名為copy的模組,它提供了copy()deepcopy()函式,可以建立可變值的副本,而不是隻複製參考。

import copy

spam = ['A', 'B', 'C']
cheese = copy.copy(spam)  # 複製列表
cheese[1] = 42  # 修改複製的列表
print(spam)  # 輸出:['A', 'B', 'C'],原始列表未被修改
print(cheese)  # 輸出:['A', 42, 'C'],複製的列表被修改

如果您需要複製的列表包含其他列表,則需要使用deepcopy()函式來確保所有巢狀列表都被正確複製。

矩陣螢幕保護程式範例

讓我們來建立一個簡單的矩陣螢幕保護程式,類別似於電影《矩陣》中出現的數字雨效果。以下是實作這個效果的Python程式碼:

import random
import sys
import time

WIDTH = 70  # 螢幕寬度

try:
    # 主迴圈
    while True:
        # 清空螢幕
        sys.stdout.write('\n' * 50)

        # 繪製矩陣效果
        for _ in range(WIDTH):
            for _ in range(WIDTH):
                if random.random() < 0.1:  # 10% 的機率顯示數字
                    sys.stdout.write(str(random.randint(0, 9)))
                else:
                    sys.stdout.write(' ')
            sys.stdout.write('\n')

        # 暫停一會兒
        time.sleep(0.1)

except KeyboardInterrupt:
    print('停止矩陣螢幕保護程式')

這個程式碼會建立一個簡單的矩陣效果,隨機顯示數字和空格,以模擬數字雨的效果。您可以按下Ctrl+C來停止程式。

Matrix雨效果程式設計

程式架構與邏輯

Matrix雨效果程式是一種模擬滴落在螢幕上的二進位制碼流的視覺效果。這個程式的核心是使用一個列表(columns)來追蹤每一欄的狀態,決定是否顯示空白或二進位制數字(0或1)。

主要程式邏輯

  1. 初始化欄狀態:建立一個列表columns,其中包含70個整數,代表螢幕上的70欄。每個整數初始值為0,表示該欄目前沒有二進位制數字流。
  2. 迴圈更新欄狀態:程式不斷迴圈更新每一欄的狀態。
    • 隨機啟動新流:對於每一欄,有2%的機率隨機啟動一個新的二進位制數字流,長度在4到14之間。
    • 更新欄內容:如果欄的狀態值為0,則顯示空白;否則,顯示一個隨機的二進位制數字(0或1),並將該欄的狀態值減1。
  3. 繪製螢幕:根據每一欄的狀態,繪製出當前的螢幕畫面。
  4. 暫停與重覆:程式暫停一段時間(例如0.1秒),然後重覆上述過程,創造出動態的滾動效果。

實作細節

  • 使用random模組:來生成隨機數字,決定是否啟動新流以及顯示哪個二進位制數字。
  • time.sleep()函式:用於暫停程式執行一段時間,控制動畫的速度。
  • 鍵盤中斷處理:使用try-except塊捕捉KeyboardInterrupt異常,當使用者按下Ctrl+C時,程式會終止。

程式碼實作

import random
import time
import sys

WIDTH = 70  # 螢幕寬度(欄數)

# 初始化欄狀態
columns = [0] * WIDTH

try:
    while True:
        # Loop over each column
        for i in range(WIDTH):
            if random.random() < 0.02:
                # Restart a stream counter on this column
                columns[i] = random.randint(4, 14)
            
            # Print a character in this column
            if columns[i] == 0:
                print(' ', end='')
            else:
                # Print a 0 or 1
                print(random.choice([0, 1]), end='')
                columns[i] -= 1  # Decrement the column value
        
        print()  # Print a newline at the end of the row
        time.sleep(0.1)  # Pause for a moment
        
except KeyboardInterrupt:
    sys.exit()  # When Ctrl-C is pressed, end the program

程式碼解析:隨機二進位制流生成器

本程式碼是一個簡單的隨機二進位制流生成器,使用Python語言實作。下面是程式碼的詳細解析:

引入模組和設定常數

import random, sys, time
WIDTH = 70  # The number of columns

程式碼首先引入了三個模組:randomsystimerandom模組用於生成隨機數字,sys模組用於離開程式,time模組用於暫停程式執行。然後,設定了一個常數WIDTH,代表輸出視窗的寬度(欄位數)。

主要程式邏輯

try:
    columns = [0] * WIDTH
    while True:
        for i in range(WIDTH):
            if random.random() < 0.02:
                columns[i] = random.randint(4, 14)
            # Print a character in this column:
            if columns[i] == 0:
                print(' ', end='')
            else:
                print(random.choice([0, 1]), end='')
        print()
except KeyboardInterrupt:
    sys.exit()

程式碼的主要邏輯放在一個try區塊中,以捕捉使用者按下Ctrl+C時引發的KeyboardInterrupt異常。

  1. 初始化一個列表columns,包含WIDTH個元素,全部設為0。
  2. 進入一個無限迴圈while True
  3. 在每次迴圈中,遍歷每個欄位(使用for i in range(WIDTH))。
  4. 對每個欄位,有2%的機率(使用random.random() < 0.02)將該欄位的計數器設為一個隨機數字之間4和14(使用random.randint(4, 14))。
  5. 根據欄位的計數器值決定是否輸出一個隨機的二進位制數字(0或1)或一個空格。如果計數器為0,則輸出空格;否則,使用random.choice([0, 1])選擇一個隨機的二進位制數字並輸出。
  6. 輸出完成後,換行(使用print())。

錯誤處理

except KeyboardInterrupt:
    sys.exit()

如果使用者按下Ctrl+C,程式會捕捉到KeyboardInterrupt異常,並使用sys.exit()離開程式。

生成二進位制樹狀圖

import random
import time
import sys

# 定義樹狀圖的列數
columns = [10, 10, 10, 10, 10, 10, 10, 10, 10, 10]

while True:
    # 清空樹狀圖
    for i in range(len(columns)):
        # 判斷是否需要印出二進位制數字
        if columns[i] > 0:
            # 隨機選擇 0 或 1
            print(random.choice([0, 1]), end='')
            # 減少計數器
            columns[i] -= 1
        else:
            # 印出空格
            print(' ', end='')
    
    # 印出換行符號
    print()
    
    # 暫停 0.1 秒
    time.sleep(0.1)

    # 檢查是否需要離開
    try:
        # 程式繼續執行
        pass
    except KeyboardInterrupt:
        # 當使用者按下 Ctrl-C 時,離開程式
        sys.exit()

內容解密:

上述程式碼使用 random.choice() 函式隨機選擇 0 或 1,並將其印出到螢幕上。同時,程式碼也會減少計數器 columns[i] 的值,以便在下一次迴圈中不再印出二進位制數字。當計數器的值為 0 時,程式碼會印出空格。程式碼使用 time.sleep(0.1) 函式暫停 0.1 秒,以便創造動畫效果。當使用者按下 Ctrl-C 時,程式碼會捕捉 KeyboardInterrupt 例外並離開程式。

圖表翻譯:

圖表翻譯:

上述 Plantuml 圖表展示了程式碼的流程。程式碼從開始處開始,然後印出二進位制樹狀圖,減少計數器,印出空格,暫停 0.1 秒,檢查是否需要離開,並最終離開程式。

Practice Questions 解答

  1. 問題:什麼是 []? 答案:[] 是一個空列表。

  2. 問題:如何將 ‘hello’ 指定為變數 spam 中的第三個值(假設 spam 包含 [2, 4, 6, 8, 10])? 答案:spam[2] = ‘hello’。

  3. 問題:假設 spam 包含 [‘a’, ‘b’, ‘c’, ’d’],spam[int(int(‘3’ * 2) // 11)] 的值是什麼? 答案:首先計算 int(‘3’ * 2) = int(‘33’) = 33,然後 33 // 11 = 3,因此 spam[3] = ’d’。

  4. 問題:假設 spam 包含 [‘a’, ‘b’, ‘c’, ’d’],spam[-1] 的值是什麼? 答案:spam[-1] = ’d’,因為 -1 指的是列表中的最後一個元素。

  5. 問題:假設 spam 包含 [‘a’, ‘b’, ‘c’, ’d’],spam[:2] 的值是什麼? 答案:spam[:2] = [‘a’, ‘b’],因為 :2 表示從開始到索引 2(不含) 的切片。

  6. 問題:假設 bacon 包含 [3.14, ‘cat’, 11, ‘cat’, True],bacon.index(‘cat’) 的值是什麼? 答案:bacon.index(‘cat’) = 1,因為 ‘cat’ 首次出現的索引是 1。

  7. 問題:假設 bacon 包含 [3.14, ‘cat’, 11, ‘cat’, True],bacon.append(99) 會使 bacon 的值變成什麼? 答案:bacon 會變成 [3.14, ‘cat’, 11, ‘cat’, True, 99]。

  8. 問題:假設 bacon 包含 [3.14, ‘cat’, 11, ‘cat’, True],bacon.remove(‘cat’) 會使 bacon 的值變成什麼? 答案:bacon 會變成 [3.14, 11, ‘cat’, True],因為 remove() 只移除第一個匹配的元素。

  9. 問題:列表的串接和複製運算子分別是什麼? 答案:串接運算子是 +,複製運算子是 *。

  10. 問題:append() 和 insert() 列表方法之間的差異是什麼? 答案:append() 在列表末尾新增一個元素,而 insert() 可以在列表的任意位置新增一個元素。

  11. 問題:有哪兩種方法可以從列表中移除值? 答案:可以使用 remove() 或 del 刪除特定索引或值的元素。

  12. 問題:列出列表值與字串值相似的幾種方式。 答案:列表和字串都可以使用索引、切片和串接,並且都有 len() 函式。

  13. 問題:列表和元組之間的差異是什麼? 答案:列表是可變的,而元組是不可變的。

  14. 問題:如何寫出只包含整數 42 的元組值? 答案:(42,),注意逗號的使用以區別單個元素的元組和普通括號。

  15. 問題:如何從列表值獲得元組形式?如何從元組值獲得列表形式? 答案:使用 tuple() 函式可以從列表獲得元組,而使用 list() 函式可以從元組獲得列表。

  16. 問題:包含列表值的變數實際上包含的是什麼? 答案:它們包含的是對列表物件的參照,而不是列表本身。

Practice Programs 解答

Comma Code

def comma_code(lst):
    if len(lst) == 0:
        return ''
    elif len(lst) == 1:
        return lst[0]
    else:
        return ', '.join(lst[:-1]) + ', and ' + lst[-1]

# 測試
spam = ['apples', 'bananas', 'tofu', 'cats']
print(comma_code(spam))  # 輸出: apples, bananas, tofu, and cats

Coin Flip Streaks

import random

def coin_flip_streaks():
    number_of_streaks = 0
    for experiment_number in range(10000):
        # 生成一個包含 100 個隨機硬幣翻轉結果的列表
        flips = [random.choice(['H', 'T']) for _ in range(100)]
        
        # 檢查是否有六個連續的頭或尾
        for i in range(len(flips) - 5):
            if flips[i:i+6].count(flips[i]) == 6:
                number_of_streaks += 1
                break
    
    # 計算百分比
    percentage = (number_of_streaks / 10000) * 100
    print(f'六個連續硬幣翻轉出現次數百分比: {percentage}%')

coin_flip_streaks()

這些程式碼提供了對應問題的解決方案,並展示瞭如何使用 Python 解決這些問題。

使用 Python 進行資料結構與字典操作

在本章中,我們將探討 Python 中的字典(dictionary)資料結構。字典是一種可變的集合,允許我們使用不同的資料型別作為索引鍵(key),而不僅僅是整數。這使得字典成為儲存和組織資料的一種靈活方式。

字典的基本操作

字典是使用大括號 {} 來定義的。以下是如何建立一個字典的範例:

my_cat = {'size': 'fat', 'color': 'gray', 'age': 17}

在這個範例中,my_cat 是一個字典,它包含三個鍵值對:'size''color''age'。我們可以使用這些鍵來存取相應的值:

print(my_cat['size'])  # 輸出:'fat'
print(my_cat['color'])  # 輸出:'gray'
print(my_cat['age'])  # 輸出:17

字典也可以使用整數作為鍵,但它們不需要從 0 開始,也可以是任意整數:

spam = {12345: 'Luggage Combination', 42: 'The Answer'}
print(spam[12345])  # 輸出:'Luggage Combination'
print(spam[42])  # 輸出:'The Answer'

字典與列表的比較

與列表不同,字典中的專案是無序的。這意味著在字典中沒有「第一個」或「最後一個」專案的概念。列表的順序對於確定兩個列表是否相等是重要的,但在字典中,鍵值對的順序不重要:

spam = ['cats', 'dogs', 'moose']
bacon = ['dogs', 'moose', 'cats']
print(spam == bacon)  # 輸出:False

eggs = {'name': 'Zophie', 'species': 'cat', 'age': 8}
ham = {'species': 'cat', 'age': 8, 'name': 'Zophie'}
print(eggs == ham)  # 輸出:True

使用字典進行資料結構

字典可以用來儲存多個有關同一件事物的資料。例如,我們可以建立一個字典來儲存一隻貓的資訊:

my_cat = {'name': 'Zophie', 'species': 'cat', 'age': 8}

這個字典包含三個鍵值對:'name''species''age'。我們可以使用這些鍵來存取相應的值:

print(my_cat['name'])  # 輸出:'Zophie'
print(my_cat['species'])  # 輸出:'cat'
print(my_cat['age'])  # 輸出:8
內容解密:

在上面的範例中,我們建立了一個字典 my_cat 來儲存一隻貓的資訊。字典包含三個鍵值對:'name''species''age'。我們可以使用這些鍵來存取相應的值。這種方式可以讓我們輕鬆地儲存和組織資料。

圖表翻譯:

以下是使用 Plantuml 語法繪製的一個簡單圖表,展示了字典的結構: 這個圖表展示了字典的基本結構,包括鍵、值和鍵值對。

字典的使用和操作

字典(dictionary)是一種強大的資料結構,允許您使用鍵(key)存取和操作值(value)。在 Python 中,字典是使用大括號 {} 來定義的,鍵和值之間使用冒號 : 分隔。

字典的基本操作

以下是一些基本的字典操作:

  • 建立字典:my_dict = {'name': 'John', 'age': 30}
  • 存取值:my_dict['name']
  • 更新值:my_dict['age'] = 31
  • 刪除鍵值對:del my_dict['age']
  • 檢查鍵是否存在:if 'name' in my_dict:
  • 取得所有鍵:my_dict.keys()
  • 取得所有值:my_dict.values()

字典的應用

字典可以用於儲存和操作各種資料,例如:

  • 儲存朋友的生日:birthdays = {'Alice': 'Apr 1', 'Bob': 'Dec 12'}
  • 儲存使用者的資料:user_data = {'name': 'John', 'age': 30, 'email': '[email protected]'}

字典的遍歷

您可以使用 .items() 方法來遍歷字典的所有鍵值對:

my_dict = {'name': 'John', 'age': 30}
for key, value in my_dict.items():
    print(f"{key}: {value}")

字典的合併

您可以使用 .update() 方法來合併兩個字典:

dict1 = {'name': 'John', 'age': 30}
dict2 = {'email': '[email protected]', 'phone': '1234567890'}
dict1.update(dict2)
print(dict1)  # {'name': 'John', 'age': 30, 'email': '[email protected]', 'phone': '1234567890'}

內容解密:

在上面的程式碼中,我們建立了兩個字典 dict1dict2,然後使用 .update() 方法將 dict2 合併到 dict1 中。這樣就可以將兩個字典的資料合併成一個字典。

圖表翻譯:

在這個圖表中,我們展示瞭如何將兩個字典合併成一個字典,並儲存合併後的資料。

字典方法:keys()、values() 和 items()

在 Python 中,字典(dictionary)是一種重要的資料結構,允許您儲存和操作鍵值對。字典提供了多種方法來存取和操作其內容,包括 keys()、values()items()

keys() 方法

keys() 方法傳回一個字典的所有鍵的檢視(view),它是一個可迭代的物件,包含了字典中的所有鍵。這個檢視不是一個列表,因此您不能修改它,也不能使用 append() 方法新增新的鍵。

spam = {'color': 'red', 'age': 42}
print(spam.keys())  # Output: dict_keys(['color', 'age'])

values() 方法

values() 方法傳回一個字典的所有值的檢視(view),它是一個可迭代的物件,包含了字典中的所有值。與 keys() 方法類別似,這個檢視不是一個列表,因此您不能修改它,也不能使用 append() 方法新增新的值。

spam = {'color': 'red', 'age': 42}
print(spam.values())  # Output: dict_values(['red', 42])

items() 方法

items() 方法傳回一個字典的所有鍵值對的檢視(view),它是一個可迭代的物件,包含了字典中的所有鍵值對。這個檢視不是一個列表,因此您不能修改它,也不能使用 append() 方法新增新的鍵值對。

spam = {'color': 'red', 'age': 42}
print(spam.items())  # Output: dict_items([('color', 'red'), ('age', 42)])

使用 for 迴圈迭代字典

您可以使用 for 迴圈來迭代字典的鍵、值或鍵值對。以下是幾個範例:

spam = {'color': 'red', 'age': 42}

# 迭代鍵
for key in spam.keys():
    print(key)

# 迭代值
for value in spam.values():
    print(value)

# 迭代鍵值對
for key, value in spam.items():
    print(f"{key}: {value}")

字典迭代與檢查

在 Python 中,字典(dictionary)是一種重要的資料結構,允許我們使用鍵(key)存取和操作值(value)。當我們需要遍歷字典中的所有鍵、值或鍵值對時,可以使用 keys()、values()items() 方法。

迭代字典中的鍵

要迭代字典中的所有鍵,可以使用 keys() 方法。這個方法傳回一個 dict_keys 物件,它包含了字典中的所有鍵。以下是範例:

spam = {'color': 'red', 'age': 42}
for k in spam.keys():
    print(k)

輸出結果將是:

color
age

迭代字典中的值

如果你想要迭代字典中的所有值,可以使用 values() 方法。這個方法傳回一個 dict_values 物件,它包含了字典中的所有值。以下是範例:

spam = {'color': 'red', 'age': 42}
for v in spam.values():
    print(v)

輸出結果將是:

red
42

迭代字典中的鍵值對

如果你想要同時迭代字典中的鍵和值,可以使用 items() 方法。這個方法傳回一個 dict_items 物件,它包含了字典中的所有鍵值對。以下是範例:

spam = {'color': 'red', 'age': 42}
for i in spam.items():
    print(i)

輸出結果將是:

('color', 'red')
('age', 42)

注意,每個鍵值對都是一個元組(tuple),其中第一個元素是鍵,第二個元素是值。

檢查鍵或值是否存在

你可以使用 innot in 運算元來檢查某個鍵或值是否存在於字典中。以下是範例:

spam = {'color': 'red', 'age': 42}
print('color' in spam.keys())  # True
print('age' not in spam.keys())  # False
print('red' in spam.values())  # True

這些方法和運算元使得你可以方便地操作和檢查字典中的資料。

圖表翻譯:

這個圖表展示瞭如何使用 keys()、values()items() 方法來迭代字典中的資料,以及如何使用 innot in 運算元來檢查鍵或值是否存在。

字典的使用和操作

字典(dictionary)是一種重要的資料結構,允許我們使用鍵(key)來存取和操作值(value)。在 Python 中,字典是使用大括號 {} 來定義的,鍵和值之間使用冒號 : 來分隔。

存取字典中的值

要存取字典中的值,可以使用其對應的鍵。例如:

spam = {'color': 'red', 'age': 42}
print(spam['color'])  # 輸出:red
print(spam['age'])  # 輸出:42

如果鍵不存在於字典中,則會引發 KeyError 例外。

檢查鍵是否存在

可以使用 in 運算元來檢查鍵是否存在於字典中:

spam = {'color': 'red', 'age': 42}
print('color' in spam)  # 輸出:True
print('eggs' in spam)  # 輸出:False

也可以使用 keys() 方法來取得字典中的所有鍵:

spam = {'color': 'red', 'age': 42}
print(list(spam.keys()))  # 輸出:['color', 'age']

使用 get() 方法

get() 方法允許我們提供一個預設值,如果鍵不存在於字典中,則傳回該預設值:

picnic_items = {'apples': 5, 'cups': 2}
print(picnic_items.get('cups', 0))  # 輸出:2
print(picnic_items.get('eggs', 0))  # 輸出:0

這樣可以避免因為鍵不存在而引發 KeyError 例外。

迭代字典中的鍵和值

可以使用 items() 方法來迭代字典中的鍵和值:

spam = {'color': 'red', 'age': 42}
for k, v in spam.items():
    print(f'Key: {k}, Value: {v}')
# 輸出:
# Key: color, Value: red
# Key: age, Value: 42

這樣可以方便地存取和操作字典中的所有鍵和值。

圖表翻譯:

內容解密:

上述程式碼示範瞭如何使用字典、存取字典中的值、檢查鍵是否存在、使用 get() 方法以及迭代字典中的鍵和值。這些操作是 Python 中非常重要的基礎知識,需要牢固掌握。

字典中的預設值

在 Python 中,當您試圖存取一個不存在的鍵的值時,會引發一個 KeyError。為了避免這種情況,您可以使用 setdefault() 方法來設定預設值。

檢查鍵是否存在

在存取一個鍵的值之前,您可以使用 in 運算子來檢查鍵是否存在於字典中。以下是一個範例:

spam = {'name': 'Pooka', 'age': 5}

if 'color' not in spam:
    spam['color'] = 'black'

print(spam)  # {'name': 'Pooka', 'age': 5, 'color': 'black'}

使用 setdefault() 方法

setdefault() 方法提供了一種更簡潔的方式來設定預設值。它的語法如下:

dict.setdefault(key, default_value)

其中 key 是您要檢查的鍵,default_value 是如果鍵不存在時要設定的值。

以下是一個範例:

spam = {'name': 'Pooka', 'age': 5}

spam.setdefault('color', 'black')
print(spam)  # {'name': 'Pooka', 'age': 5, 'color': 'black'}

spam.setdefault('color', 'white')
print(spam)  # {'name': 'Pooka', 'age': 5, 'color': 'black'}

如您所見,當鍵 'color' 不存在時,setdefault() 方法會設定其值為 'black'。當鍵已經存在時,setdefault() 方法不會改變其值。

範例程式

以下是一個簡短的程式,使用 setdefault() 方法來計算一個字串中每個字元的出現次數:

message = 'It was a bright cold day in April, and'

count = {}
for character in message:
    count.setdefault(character, 0)
    count[character] += 1

print(count)

這個程式會輸出一個字典,其中每個鍵是字串中的字元,值是其出現次數。

建立互動式西洋棋棋盤模擬器

西洋棋是一種策略性遊戲,玩家透過移動棋子來試圖將對方的王將死。要建立一個互動式西洋棋棋盤模擬器,我們需要設計一個資料結構來代表棋盤和棋子。

資料結構設計

我們可以使用一個Python字典來代表棋盤,每個鍵代表一個棋格,值代表該格子上的棋子。例如,{'a1': 'wR', 'b1': 'wN', 'c1': 'wB'}代表了一個棋盤,其中a1格子上有一個白色的車,b1格子上有一個白色的騎士,c1格子上有一個白色的象。

程式碼實作

import sys
import copy

# 定義初始棋盤組態
STARTING_PIECES = {
    'a8': 'bR', 'b8': 'bN', 'c8': 'bB', 'd8': 'bQ', 'e8': 'bK', 'f8': 'bB', 'g8': 'bN', 'h8': 'bR',
    'a7': 'bP', 'b7': 'bP', 'c7': 'bP', 'd7': 'bP', 'e7': 'bP', 'f7': 'bP', 'g7': 'bP', 'h7': 'bP',
    'a1': 'wR', 'b1': 'wN', 'c1': 'wB', 'd1': 'wQ', 'e1': 'wK', 'f1': 'wB', 'g1': 'wN', 'h1': 'wR',
    'a2': 'wP', 'b2': 'wP', 'c2': 'wP', 'd2': 'wP', 'e2': 'wP', 'f2': 'wP', 'g2': 'wP', 'h2': 'wP'
}

# 定義棋盤範本
BOARD_TEMPLATE = """
  a b c d e f g h
8 {} {} {} {} {} {} {} {}
7 {} {} {} {} {} {} {} {}
6 {} {} {} {} {} {} {} {}
5 {} {} {} {} {} {} {} {}
4 {} {} {} {} {} {} {} {}
3 {} {} {} {} {} {} {} {}
2 {} {} {} {} {} {} {} {}
1 {} {} {} {} {} {} {} {}
"""

def print_board(board):
    # 將棋盤組態插入範本中
    print(BOARD_TEMPLATE.format(
        board.get('a8', ''), board.get('b8', ''), board.get('c8', ''), board.get('d8', ''), board.get('e8', ''), board.get('f8', ''), board.get('g8', ''), board.get('h8', ''),
        board.get('a7', ''), board.get('b7', ''), board.get('c7', ''), board.get('d7', ''), board.get('e7', ''), board.get('f7', ''), board.get('g7', ''), board.get('h7', ''),
        board.get('a6', ''), board.get('b6', ''), board.get('c6', ''), board.get('d6', ''), board.get('e6', ''), board.get('f6', ''), board.get('g6', ''), board.get('h6', ''),
        board.get('a5', ''), board.get('b5', ''), board.get('c5', ''), board.get('d5', ''), board.get('e5', ''), board.get('f5', ''), board.get('g5', ''), board.get('h5', ''),
        board.get('a4', ''), board.get('b4', ''), board.get('c4', ''), board.get('d4', ''), board.get('e4', ''), board.get('f4', ''), board.get('g4', ''), board.get('h4', ''),
        board.get('a3', ''), board.get('b3', ''), board.get('c3', ''), board.get('d3', ''), board.get('e3', ''), board.get('f3', ''), board.get('g3', ''), board.get('h3', ''),
        board.get('a2', ''), board.get('b2', ''), board.get('c2', ''), board.get('d2', ''), board.get('e2', ''), board.get('f2', ''), board.get('g2', ''), board.get('h2', ''),
        board.get('a1', ''), board.get('b1', ''), board.get('c1', ''), board.get('d1', ''), board.get('e1', ''), board.get('f1', ''), board.get('g1', ''), board.get('h1', '')
    ))

def main():
    # 複製初始棋盤組態
    board = copy.copy(STARTING_PIECES)
    
    # 列印初始棋盤
    print_board(board)

if __name__ == '__main__':
    main()

執行結果

  a b c d e f g h
8 bR bN bB bQ bK bB bN bR
7 bP bP bP bP bP bP bP bP
6         
5         
4         
3         
2 wP wP wP wP wP wP wP wP
1 wR wN wB wQ wK wB wN wR

這個程式碼建立了一個互動式西洋棋棋盤模擬器,使用Python字典來代表棋盤和棋子。它可以列印出初始的棋盤組態,並提供了一個基礎框架供未來的開發使用。

瞭解矩陣運算的基礎

矩陣運算是線性代數中的一個重要概念,廣泛應用於各個領域,如物理、工程、電腦科學等。在這篇文章中,我們將探討矩陣運算的基礎知識,包括矩陣的定義、矩陣的加法和乘法、矩陣的轉置和逆矩陣等。

矩陣的定義

矩陣是一個由數字或符號組成的二維陣列,每個元素都有其特定的位置。矩陣通常用大寫字母表示,如A、B、C等。矩陣的行和列數稱為矩陣的維度,通常用m x n表示,其中m是行數,n是列數。

矩陣的加法

矩陣的加法是指兩個矩陣對應元素的相加。只有當兩個矩陣的維度相同時,才能進行加法運算。例如,假設有兩個矩陣A和B,它們的維度都是2 x 2,那麼它們的加法運算可以表示為:

矩陣的乘法

矩陣的乘法是指兩個矩陣對應元素的相乘,但與加法不同的是,乘法需要滿足一定的條件。只有當第一個矩陣的列數與第二個矩陣的行數相等時,才能進行乘法運算。例如,假設有兩個矩陣A和B,A的維度是2 x 3,B的維度是3 x 2,那麼它們的乘法運算可以表示為:

內容解密:

在上述例子中,矩陣A和B的乘法運算可以得到一個新的矩陣C。這個過程需要將A的每一行元素與B的每一列元素相乘,並將結果相加。這樣就可以得到C矩陣中的每一個元素。

矩陣的轉置

矩陣的轉置是指將矩陣的行和列互換。轉置後的矩陣通常用A^T表示,其中A是原矩陣。例如,假設有一個矩陣A,其維度是2 x 3,那麼其轉置A^T的維度就是3 x 2。

圖表翻譯:

在這個圖表中,我們可以看到矩陣A和其轉置A^T之間的關係。透過轉置運算,我們可以得到一個新的矩陣,其行和列與原矩陣相反。

矩陣的逆

矩陣的逆是指一個能夠與原矩陣相乘得到單位矩陣的矩陣。只有當矩陣是可逆的時候,才能找到其逆。例如,假設有一個矩陣A,其維度是2 x 2,那麼其逆A^-1可以表示為:

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title Python資料結構變數型別與字典操作

package "NumPy 陣列操作" {
    package "陣列建立" {
        component [ndarray] as arr
        component [zeros/ones] as init
        component [arange/linspace] as range
    }

    package "陣列操作" {
        component [索引切片] as slice
        component [形狀變換 reshape] as reshape
        component [堆疊 stack/concat] as stack
        component [廣播 broadcasting] as broadcast
    }

    package "數學運算" {
        component [元素運算] as element
        component [矩陣運算] as matrix
        component [統計函數] as stats
        component [線性代數] as linalg
    }
}

arr --> slice : 存取元素
arr --> reshape : 改變形狀
arr --> broadcast : 自動擴展
arr --> element : +, -, *, /
arr --> matrix : dot, matmul
arr --> stats : mean, std, sum
arr --> linalg : inv, eig, svd

note right of broadcast
  不同形狀陣列
  自動對齊運算
end note

@enduml

在這個過程中,我們需要找到一個能夠與原矩陣A相乘得到單位矩陣的新矩陣A^-1。

從技術架構視角來看,Python 的變數與資料型別系統展現了其靈活性與效率。深入剖析其底層實作,可以發現 Python 的變數本質上是指標,指向特定記憶體位置的物件,而非直接儲存值。這種設計賦予了 Python 動態型別的特性,但也引入了變數指定與修改時潛在的副作用,特別是針對可變物件如列表和字典。理解指標的概念對於正確操作列表、字典,以及函式引數傳遞至關重要,否則可能導致非預期的結果。Python 提供的 copy()deepcopy() 函式為處理可變物件提供了有效的解決方案,可以避免修改原始資料的風險。對於追求程式碼穩健性的開發者而言,深入理解這些機制至關重要。展望未來,隨著 Python 應用場景日益複雜,更精細的記憶體管理與資料結構操作技巧將成為進階開發者的必備技能。玄貓認為,掌握這些核心概念,才能在 Python 開發的道路上走得更穩、更遠。