第4章 數據結構¶
前言¶
Python提供了豐富的內置數據結構,包括字符串(String)、列表(List)、元組(Tuple)、字典(Dictionary)和集合(Set)。這些數據結構各有特點,適用於不同的應用場景。掌握這些數據結構的使用方法和特性,是Python編程的基礎。本章將詳細介紹每種數據結構的創建、操作和應用,並通過大量的實例代碼幫助讀者理解和掌握。
本系列文章所使用到的示例源碼:Python從入門到精通示例代碼
4.1 字符串(String)¶
4.1.1 字符串基礎操作¶
字符串的定義與創建¶
Python中字符串可以用單引號、雙引號或三引號來定義。三引號通常用於多行字符串。
# 字符串的創建方式
single_quote = 'Hello World'
double_quote = "Hello World"
triple_quote = """這是一個
多行字符串
示例"""
# 原始字符串(r-string)- 不轉義特殊字符
raw_string = r'C:\Users\Python\test.txt'
# 字節字符串(b-string)
byte_string = b'Hello World'
print("單引號字符串:", single_quote)
print("雙引號字符串:", double_quote)
print("三引號字符串:")
print(triple_quote)
print("原始字符串:", raw_string)
print("字節字符串:", byte_string)
print("字節字符串類型:", type(byte_string))
輸出結果:
單引號字符串: Hello World
雙引號字符串: Hello World
三引號字符串:
這是一個
多行字符串
示例
原始字符串: C:\Users\Python\test.txt
字節字符串: b'Hello World'
字節字符串類型: <class 'bytes'>
字符串的索引與切片¶
字符串支持正向索引(從0開始)和負向索引(從-1開始),還支持切片操作。
# 字符串索引和切片示例
text = "Python編程"
# 正向索引
print("第一個字符:", text[0]) # P
print("第二個字符:", text[1]) # y
# 負向索引
print("最後一個字符:", text[-1]) # 程
print("倒數第二個字符:", text[-2]) # 編
# 切片操作 [start:end:step]
print("前3個字符:", text[:3]) # Pyt
print("從第2個到第5個字符:", text[2:6]) # thon
print("最後3個字符:", text[-3:]) # n編程
print("每隔一個字符:", text[::2]) # Pto編
print("反轉字符串:", text[::-1]) # 程編nohtyP
輸出結果:
第一個字符: P
第二個字符: y
最後一個字符: 程
倒數第二個字符: 編
前3個字符: Pyt
從第2個到第5個字符: thon
最後3個字符: n編程
每隔一個字符: Pto編
反轉字符串: 程編nohtyP
字符串的基本操作¶
# 字符串基本操作示例
str1 = "Hello"
str2 = "World"
# 長度獲取
print("str1長度:", len(str1)) # 5
# 字符串連接
result1 = str1 + " " + str2
print("連接結果:", result1) # Hello World
# 字符串重複
result2 = str1 * 3
print("重複結果:", result2) # HelloHelloHello
# 成員檢測
print("'ell' in str1:", 'ell' in str1) # True
print("'xyz' not in str1:", 'xyz' not in str1) # True
# 字符串的不可變性演示
original = "Python"
print("原始字符串:", original)
# original[0] = 'J' # 這行代碼會報錯,因爲字符串不可變
modified = 'J' + original[1:] # 正確的修改方式
print("修改後的字符串:", modified)
輸出結果:
str1長度: 5
連接結果: Hello World
重複結果: HelloHelloHello
'ell' in str1: True
'xyz' not in str1: True
原始字符串: Python
修改後的字符串: Jython
4.1.2 字符串格式化¶
Python提供了多種字符串格式化方式,從傳統的%操作符到現代的f-string。
傳統格式化(%操作符)¶
# 傳統格式化示例
name = "張三"
age = 25
height = 175.5
# 基本格式化
print("姓名: %s, 年齡: %d, 身高: %.1f釐米" % (name, age, height))
# 格式化參數控制
print("浮點數: %10.2f" % 3.1415926) # 寬度10,精度2
print("整數補零: %05d" % 42) # 寬度5,補零
print("左對齊: %-10s" % "Python") # 寬度10,左對齊
輸出結果:
姓名: 張三, 年齡: 25, 身高: 175.5釐米
浮點數: 3.14
整數補零: 00042
左對齊: Python
str.format()方法¶
# str.format()方法示例
name = "李四"
age = 30
# 位置參數
print("姓名: {}, 年齡: {}".format(name, age))
# 索引參數
print("年齡: {1}, 姓名: {0}".format(name, age))
# 關鍵字參數
print("姓名: {name}, 年齡: {age}".format(name=name, age=age))
# 格式化規範
pi = 3.1415926
print("數字格式化: {:.2f}".format(pi)) # 保留2位小數
print("百分比: {:.1%}".format(0.25)) # 百分比格式,保留1位小數
print("科學計數法: {:.2e}".format(1000000)) # 科學計數法,保留2位小數
print("千位分隔符: {:,}".format(1234567)) # 添加千位分隔符
輸出結果:
姓名: 李四, 年齡: 30
年齡: 30, 姓名: 李四
姓名: 李四, 年齡: 30
數字格式化: 3.14
百分比: 25.0%
科學計數法: 1.00e+06
千位分隔符: 1,234,567
f-string格式化(推薦)¶
f-string是Python 3.6引入的新特性,是目前最推薦的字符串格式化方式。
# f-string格式化示例
name = "王五"
age = 35
height = 180.5
# 基本語法
print(f"姓名: {name}, 年齡: {age}, 身高: {height}釐米")
# 表達式嵌入
print(f"年齡5年後: {age + 5}")
print(f"身高(英尺): {height / 30.48:.2f}")
# 格式化選項
pi = 3.1415926
print(f"π值: {pi:.4f}") # 保留4位小數
print(f"大數字: {1000000:,}") # 添加千位分隔符
print(f"二進制: {42:b}") # 二進制表示
print(f"十六進制: {42:x}") # 十六進制表示
print(f"居中對齊: {name:^10}") # 居中對齊,寬度10
輸出結果:
姓名: 王五, 年齡: 35, 身高: 180.5釐米
年齡5年後: 40
身高(英尺): 5.92
π值: 3.1416
大數字: 1,000,000
二進制: 101010
十六進制: 2a
居中對齊: 王五
4.1.3 字符串方法詳解¶
Python的字符串類型提供了豐富的方法,可以方便地進行各種操作。
大小寫轉換方法¶
# 大小寫轉換方法示例
text = "Hello, World!"
print("原始字符串:", text)
print("全部大寫:", text.upper())
print("全部小寫:", text.lower())
print("首字母大寫:", text.capitalize())
print("每個單詞首字母大寫:", text.title())
print("大小寫互換:", text.swapcase())
輸出結果:
原始字符串: Hello, World!
全部大寫: HELLO, WORLD!
全部小寫: hello, world!
首字母大寫: Hello, world!
每個單詞首字母大寫: Hello, World!
大小寫互換: hELLO, wORLD!
查找和替換方法¶
# 查找和替換方法示例
text = "Python編程語言是一種易學易用的編程語言"
# 查找方法
print("'編程'第一次出現的位置:", text.find("編程")) # 返回索引,如果不存在返回-1
print("'編程'最後一次出現的位置:", text.rfind("編程")) # 從右側開始查找
print("'Java'是否存在:", text.find("Java")) # 不存在,返回-1
try:
print("使用index查找'編程':", text.index("編程")) # 返回索引,如果不存在拋出異常
print("使用index查找'Java':", text.index("Java")) # 不存在,拋出異常
except ValueError as e:
print(f"捕獲到異常: {e}")
# 計數方法
print("'編程'出現的次數:", text.count("編程")) # 返回出現次數
# 替換方法
print("替換'編程'爲'開發':", text.replace("編程", "開發"))
print("替換'編程'爲'開發'(只替換一次):", text.replace("編程", "開發", 1)) # 限制替換次數
輸出結果:
'編程'第一次出現的位置: 6
'編程'最後一次出現的位置: 18
'Java'是否存在: -1
使用index查找'編程': 6
捕獲到異常: substring not found
'編程'出現的次數: 2
替換'編程'爲'開發': Python開發語言是一種易學易用的開發語言
替換'編程'爲'開發'(只替換一次): Python開發語言是一種易學易用的編程語言
判斷方法¶
# 判斷方法示例
text1 = "Hello123"
text2 = "PYTHON"
text3 = " \t\n"
text4 = "Python"
# 內容判斷
print(f"'{text1}' 是否爲字母和數字: {text1.isalnum()}")
print(f"'{text1}' 是否全爲字母: {text1.isalpha()}")
print(f"'{text1}' 是否全爲數字: {text1.isdigit()}")
print(f"'123' 是否全爲數字: {'123'.isdigit()}")
# 大小寫判斷
print(f"'{text2}' 是否全爲大寫: {text2.isupper()}")
print(f"'{text4}' 是否全爲小寫: {text4.islower()}")
# 空白判斷
print(f"'{text3}' 是否全爲空白字符: {text3.isspace()}")
# 前綴後綴判斷
print(f"'{text4}' 是否以'Py'開頭: {text4.startswith('Py')}")
print(f"'{text4}' 是否以'on'結尾: {text4.endswith('on')}")
輸出結果:
'Hello123' 是否爲字母和數字: True
'Hello123' 是否全爲字母: False
'Hello123' 是否全爲數字: False
'123' 是否全爲數字: True
'PYTHON' 是否全爲大寫: True
'Python' 是否全爲小寫: False
'
' 是否全爲空白字符: True
'Python' 是否以'Py'開頭: True
'Python' 是否以'on'結尾: True
分割和連接方法¶
# 分割和連接方法示例
text = "Python,Java,C++,JavaScript"
text_lines = "第一行\n第二行\n第三行"
# 分割方法
print("按逗號分割:", text.split(",")) # 按指定分隔符分割
print("按逗號分割(限制2次):", text.split(",", 2)) # 限制分割次數
print("按行分割:\n", text_lines.splitlines()) # 按行分割
# 連接方法
words = ["Python", "是", "一種", "編程語言"]
print("使用空格連接:", " ".join(words)) # 使用指定字符連接列表元素
print("使用-連接:", "-".join(words))
輸出結果:
按逗號分割: ['Python', 'Java', 'C++', 'JavaScript']
按逗號分割(限制2次): ['Python', 'Java', 'C++,JavaScript']
按行分割:
['第一行', '第二行', '第三行']
使用空格連接: Python 是 一種 編程語言
使用-連接: Python-是-一種-編程語言
去除空白方法¶
# 去除空白方法示例
text = " Python編程 "
print(f"原始字符串: '{text}'")
print(f"去除兩端空白: '{text.strip()}'")
print(f"去除左側空白: '{text.lstrip()}'")
print(f"去除右側空白: '{text.rstrip()}'")
# 去除指定字符
text2 = "###Python###"
print(f"原始字符串: '{text2}'")
print(f"去除兩端#號: '{text2.strip('#')}'")
輸出結果:
原始字符串: ' Python編程 '
去除兩端空白: 'Python編程'
去除左側空白: 'Python編程 '
去除右側空白: ' Python編程'
原始字符串: '###Python###'
去除兩端#號: 'Python'
4.2 列表(List)¶
列表是Python中最常用的數據結構之一,它是一個有序的、可變的集合,可以存儲任意類型的數據。
4.2.1 列表的創建與訪問¶
列表的定義與特點¶
列表具有以下特點:
- 有序:元素有固定的位置
- 可變:可以修改、添加、刪除元素
- 允許重複:同一個值可以出現多次
- 異構:可以存儲不同類型的數據
# 列表的創建方法示例
# 直接創建
fruits = ["蘋果", "香蕉", "橙子"]
numbers = [1, 2, 3, 4, 5]
mixed_list = ["Python", 3.14, True, [1, 2, 3]] # 混合類型
# list()構造函數
list1 = list() # 空列表
list2 = list("Python") # 從字符串創建
list3 = list(range(5)) # 從range對象創建
# 列表推導式(簡介)
squares = [x**2 for x in range(5)] # 生成平方數列表
print("水果列表:", fruits)
print("數字列表:", numbers)
print("混合列表:", mixed_list)
print("空列表:", list1)
print("從字符串創建:", list2)
print("從range創建:", list3)
print("平方數列表:", squares)
輸出結果:
水果列表: ['蘋果', '香蕉', '橙子']
數字列表: [1, 2, 3, 4, 5]
混合列表: ['Python', 3.14, True, [1, 2, 3]]
空列表: []
從字符串創建: ['P', 'y', 't', 'h', 'o', 'n']
從range創建: [0, 1, 2, 3, 4]
平方數列表: [0, 1, 4, 9, 16]
列表的索引與切片¶
# 列表索引和切片示例
fruits = ["蘋果", "香蕉", "橙子", "葡萄", "西瓜"]
# 單個元素訪問
print("第一個元素:", fruits[0]) # 蘋果
print("最後一個元素:", fruits[-1]) # 西瓜
# 切片操作
print("前三個元素:", fruits[:3]) # ['蘋果', '香蕉', '橙子']
print("從第二個到第四個:", fruits[1:4]) # ['香蕉', '橙子', '葡萄']
print("最後兩個元素:", fruits[-2:]) # ['葡萄', '西瓜']
print("每隔一個元素:", fruits[::2]) # ['蘋果', '橙子', '西瓜']
print("反轉列表:", fruits[::-1]) # ['西瓜', '葡萄', '橙子', '香蕉', '蘋果']
# 列表的可變性演示
print("原始列表:", fruits)
fruits[1] = "芒果" # 修改第二個元素
print("修改後的列表:", fruits)
輸出結果:
第一個元素: 蘋果
最後一個元素: 西瓜
前三個元素: ['蘋果', '香蕉', '橙子']
從第二個到第四個: ['香蕉', '橙子', '葡萄']
最後兩個元素: ['葡萄', '西瓜']
每隔一個元素: ['蘋果', '橙子', '西瓜']
反轉列表: ['西瓜', '葡萄', '橙子', '香蕉', '蘋果']
原始列表: ['蘋果', '香蕉', '橙子', '葡萄', '西瓜']
修改後的列表: ['蘋果', '芒果', '橙子', '葡萄', '西瓜']
4.2.2 列表的增刪改查¶
添加元素¶
# 列表添加元素示例
fruits = ["蘋果", "香蕉"]
print("初始列表:", fruits)
# append()方法 - 在末尾添加單個元素
fruits.append("橙子")
print("append後:", fruits)
# insert()方法 - 在指定位置插入元素
fruits.insert(1, "葡萄") # 在索引1處插入
print("insert後:", fruits)
# extend()方法 - 添加多個元素
fruits.extend(["西瓜", "芒果"])
print("extend後:", fruits)
# +操作符 - 連接列表(創建新列表)
new_fruits = fruits + ["草莓", "藍莓"]
print("使用+操作符:", new_fruits)
print("原列表不變:", fruits)
# +=操作符 - 就地擴展
fruits += ["櫻桃"]
print("使用+=操作符:", fruits)
輸出結果:
初始列表: ['蘋果', '香蕉']
append後: ['蘋果', '香蕉', '橙子']
insert後: ['蘋果', '葡萄', '香蕉', '橙子']
extend後: ['蘋果', '葡萄', '香蕉', '橙子', '西瓜', '芒果']
使用+操作符: ['蘋果', '葡萄', '香蕉', '橙子', '西瓜', '芒果', '草莓', '藍莓']
原列表不變: ['蘋果', '葡萄', '香蕉', '橙子', '西瓜', '芒果']
使用+=操作符: ['蘋果', '葡萄', '香蕉', '橙子', '西瓜', '芒果', '櫻桃']
刪除元素¶
# 列表刪除元素示例
fruits = ["蘋果", "香蕉", "橙子", "葡萄", "香蕉", "西瓜"]
print("初始列表:", fruits)
# del語句 - 按索引刪除
del fruits[1] # 刪除索引1的元素
print("del刪除後:", fruits)
# remove()方法 - 刪除第一個匹配的值
fruits.remove("香蕉") # 刪除第一個"香蕉"
print("remove刪除後:", fruits)
# pop()方法 - 刪除並返回指定位置的元素
popped = fruits.pop() # 刪除最後一個元素
print(f"pop刪除的元素: {popped}")
print("pop刪除後:", fruits)
popped_index = fruits.pop(1) # 刪除索引1的元素
print(f"pop刪除的元素: {popped_index}")
print("pop刪除後:", fruits)
# clear()方法 - 清空列表
temp_list = [1, 2, 3]
print("清空前:", temp_list)
temp_list.clear()
print("清空後:", temp_list)
輸出結果:
初始列表: ['蘋果', '香蕉', '橙子', '葡萄', '香蕉', '西瓜']
del刪除後: ['蘋果', '橙子', '葡萄', '香蕉', '西瓜']
remove刪除後: ['蘋果', '橙子', '葡萄', '西瓜']
pop刪除的元素: 西瓜
pop刪除後: ['蘋果', '橙子', '葡萄']
pop刪除的元素: 橙子
pop刪除後: ['蘋果', '葡萄']
清空前: [1, 2, 3]
清空後: []
修改和查找元素¶
# 列表修改和查找示例
fruits = ["蘋果", "香蕉", "橙子", "葡萄", "香蕉"]
print("初始列表:", fruits)
# 直接賦值修改
fruits[1] = "芒果"
print("修改索引1後:", fruits)
# 切片賦值修改
fruits[1:3] = ["草莓", "藍莓", "櫻桃"] # 替換索引1-2的元素
print("切片賦值後:", fruits)
# 查找元素
print("'葡萄'的索引:", fruits.index("葡萄")) # 返回第一個匹配的索引
print("'香蕉'出現的次數:", fruits.count("香蕉")) # 統計出現次數
print("'蘋果'是否在列表中:", "蘋果" in fruits) # 成員檢測
print("'西瓜'是否在列表中:", "西瓜" in fruits)
# 處理查找異常
try:
index = fruits.index("西瓜")
except ValueError:
print("'西瓜'不在列表中")
輸出結果:
初始列表: ['蘋果', '香蕉', '橙子', '葡萄', '香蕉']
修改索引1後: ['蘋果', '芒果', '橙子', '葡萄', '香蕉']
切片賦值後: ['蘋果', '草莓', '藍莓', '櫻桃', '葡萄', '香蕉']
'葡萄'的索引: 4
'香蕉'出現的次數: 1
'蘋果'是否在列表中: True
'西瓜'是否在列表中: False
'西瓜'不在列表中
4.2.3 列表的排序與反轉¶
# 列表排序和反轉示例
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
fruits = ["香蕉", "蘋果", "橙子", "葡萄"]
print("原始數字列表:", numbers)
print("原始水果列表:", fruits)
# sort()方法 - 就地排序
numbers_copy = numbers.copy()
numbers_copy.sort() # 升序排序
print("升序排序:", numbers_copy)
numbers_copy.sort(reverse=True) # 降序排序
print("降序排序:", numbers_copy)
# 字符串排序
fruits_copy = fruits.copy()
fruits_copy.sort() # 按字母順序排序
print("水果按字母排序:", fruits_copy)
# 自定義排序規則 - 按長度排序
fruits_copy.sort(key=len)
print("水果按長度排序:", fruits_copy)
# sorted()函數 - 返回新的排序列表
sorted_numbers = sorted(numbers)
print("sorted()函數結果:", sorted_numbers)
print("原列表不變:", numbers)
# reverse()方法 - 就地反轉
numbers_copy = numbers.copy()
numbers_copy.reverse()
print("reverse()反轉:", numbers_copy)
# reversed()函數 - 返回反轉迭代器
reversed_list = list(reversed(numbers))
print("reversed()函數結果:", reversed_list)
# 列表複製
original = [1, 2, [3, 4]]
shallow_copy = original.copy() # 淺拷貝
deep_copy_demo = [1, 2, [3, 4]]
print("\n列表複製演示:")
print("原始列表:", original)
original[2][0] = 99 # 修改嵌套列表
print("修改嵌套元素後:")
print("原始列表:", original)
print("淺拷貝:", shallow_copy) # 淺拷貝會受影響
輸出結果:
原始數字列表: [3, 1, 4, 1, 5, 9, 2, 6]
原始水果列表: ['香蕉', '蘋果', '橙子', '葡萄']
升序排序: [1, 1, 2, 3, 4, 5, 6, 9]
降序排序: [9, 6, 5, 4, 3, 2, 1, 1]
水果按字母排序: ['橙子', '蘋果', '葡萄', '香蕉']
水果按長度排序: ['蘋果', '橙子', '葡萄', '香蕉']
sorted()函數結果: [1, 1, 2, 3, 4, 5, 6, 9]
原列表不變: [3, 1, 4, 1, 5, 9, 2, 6]
reverse()反轉: [6, 2, 9, 5, 1, 4, 1, 3]
reversed()函數結果: [6, 2, 9, 5, 1, 4, 1, 3]
列表複製演示:
原始列表: [1, 2, [3, 4]]
修改嵌套元素後:
原始列表: [1, 2, [99, 4]]
淺拷貝: [1, 2, [99, 4]]
4.3 元組(Tuple)¶
元組是Python中的不可變序列類型,與列表類似但不能修改。元組通常用於存儲相關但不同類型的數據。
元組的定義與特點¶
元組具有以下特點:
- 有序:元素有固定的位置
- 不可變:創建後不能修改元素
- 允許重複:同一個值可以出現多次
- 異構:可以存儲不同類型的數據
- 可哈希:可以作爲字典的鍵
# 元組的創建方法示例
# 圓括號創建
point = (3, 4)
colors = ("紅色", "綠色", "藍色")
# 逗號創建(推薦加括號以提高可讀性)
single_tuple = (42,) # 單元素元組,注意逗號
coordinates = 10, 20 # 不加括號也可以
# tuple()構造函數
empty_tuple = tuple() # 空元組
from_list = tuple([1, 2, 3, 4]) # 從列表創建
from_string = tuple("Python") # 從字符串創建
print("點座標:", point)
print("顏色元組:", colors)
print("單元素元組:", single_tuple)
print("座標:", coordinates)
print("空元組:", empty_tuple)
print("從列表創建:", from_list)
print("從字符串創建:", from_string)
print("元組類型:", type(point))
輸出結果:
點座標: (3, 4)
顏色元組: ('紅色', '綠色', '藍色')
單元素元組: (42,)
座標: (10, 20)
空元組: ()
從列表創建: (1, 2, 3, 4)
從字符串創建: ('P', 'y', 't', 'h', 'o', 'n')
元組類型: <class 'tuple'>
元組的訪問與操作¶
# 元組訪問和操作示例
fruits = ("蘋果", "香蕉", "橙子", "葡萄", "西瓜")
numbers = (1, 2, 3, 4, 5, 4, 3, 2, 1)
# 索引訪問
print("第一個水果:", fruits[0]) # 蘋果
print("最後一個水果:", fruits[-1]) # 西瓜
# 切片操作
print("前三個水果:", fruits[:3]) # ('蘋果', '香蕉', '橙子')
print("最後兩個水果:", fruits[-2:]) # ('葡萄', '西瓜')
print("每隔一個:", fruits[::2]) # ('蘋果', '橙子', '西瓜')
# 元組的不可變性演示
print("原始元組:", fruits)
# fruits[0] = "芒果" # 這行代碼會報錯,因爲元組不可變
# 但可以重新賦值整個元組
fruits = ("芒果", "香蕉", "橙子", "葡萄", "西瓜")
print("重新賦值後:", fruits)
# 元組的方法
print("數字4出現的次數:", numbers.count(4)) # 統計元素出現次數
print("數字3第一次出現的位置:", numbers.index(3)) # 查找元素索引
# 元組解包
point = (10, 20)
x, y = point # 解包到變量
print(f"x座標: {x}, y座標: {y}")
# 多變量賦值
a, b, c = 1, 2, 3 # 實際上是元組解包
print(f"a={a}, b={b}, c={c}")
輸出結果:
第一個水果: 蘋果
最後一個水果: 西瓜
前三個水果: ('蘋果', '香蕉', '橙子')
最後兩個水果: ('葡萄', '西瓜')
每隔一個: ('蘋果', '橙子', '西瓜')
原始元組: ('蘋果', '香蕉', '橙子', '葡萄', '西瓜')
重新賦值後: ('芒果', '香蕉', '橙子', '葡萄', '西瓜')
數字4出現的次數: 2
數字3第一次出現的位置: 2
x座標: 10, y座標: 20
a=1, b=2, c=3
元組的應用場景¶
# 元組應用場景示例
# 1. 函數返回多個值
def get_name_age():
"""返回姓名和年齡"""
return "張三", 25 # 實際返回的是元組
def calculate_stats(numbers):
"""計算統計信息"""
return min(numbers), max(numbers), sum(numbers) / len(numbers)
name, age = get_name_age()
print(f"姓名: {name}, 年齡: {age}")
data = [1, 2, 3, 4, 5]
min_val, max_val, avg_val = calculate_stats(data)
print(f"最小值: {min_val}, 最大值: {max_val}, 平均值: {avg_val:.2f}")
# 2. 作爲字典的鍵
student_grades = {
("張三", "數學"): 95,
("張三", "英語"): 87,
("李四", "數學"): 92,
("李四", "英語"): 89
}
print("張三的數學成績:", student_grades[("張三", "數學")])
# 3. 數據的保護 - 配置信息
DATABASE_CONFIG = (
"localhost", # 主機
5432, # 端口
"mydb", # 數據庫名
"user", # 用戶名
"password" # 密碼
)
host, port, db_name, username, password = DATABASE_CONFIG
print(f"數據庫配置: {host}:{port}/{db_name}")
# 4. 座標和點
points = [(0, 0), (1, 1), (2, 4), (3, 9)]
print("座標點列表:", points)
# 計算距離
import math
def distance(point1, point2):
"""計算兩點間距離"""
x1, y1 = point1
x2, y2 = point2
return math.sqrt((x2 - x1)**2 + (y2 - y1)**2)
dist = distance((0, 0), (3, 4))
print(f"兩點間距離: {dist:.2f}")
輸出結果:
姓名: 張三, 年齡: 25
最小值: 1, 最大值: 5, 平均值: 3.00
張三的數學成績: 95
數據庫配置: localhost:5432/mydb
座標點列表: [(0, 0), (1, 1), (2, 4), (3, 9)]
兩點間距離: 5.00
4.4 字典(Dictionary)¶
字典是Python中的映射類型,以鍵值對的形式存儲數據,通過鍵來訪問值。字典是無序的、可變的、不允許鍵重複的數據結構。
4.4.1 字典的基本操作¶
字典的定義與特點¶
字典具有以下特點:
- 無序:元素沒有固定的位置(Python 3.7+保持插入順序)
- 可變:可以修改、添加、刪除鍵值對
- 鍵唯一:不允許重複的鍵
- 鍵必須可哈希:不可變類型如字符串、數字、元組(不包含可變對象)
- 值可以是任意類型:包括可變類型
# 字典的創建方法示例
# 花括號創建
student = {"name": "張三", "age": 20, "score": 95}
empty_dict = {} # 空字典
# dict()構造函數
person = dict(name="李四", age=25, city="北京")
from_list = dict([("a", 1), ("b", 2), ("c", 3)]) # 從鍵值對列表創建
# 字典推導式
squares = {x: x**2 for x in range(5)} # 創建平方數字典
print("學生信息:", student)
print("空字典:", empty_dict)
print("人員信息:", person)
print("從列表創建:", from_list)
print("平方數字典:", squares)
print("字典類型:", type(student))
輸出結果:
學生信息: {'name': '張三', 'age': 20, 'score': 95}
空字典: {}
人員信息: {'name': '李四', 'age': 25, 'city': '北京'}
從列表創建: {'a': 1, 'b': 2, 'c': 3}
平方數字典: {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
字典類型: <class 'dict'>
字典的訪問與修改¶
# 字典訪問與修改示例
student = {"name": "張三", "age": 20, "score": 95}
print("原始字典:", student)
# 鍵值訪問
print("姓名:", student["name"]) # 通過鍵訪問值
# get()方法 - 安全訪問
print("年齡:", student.get("age")) # 通過get方法訪問值
print("地址:", student.get("address")) # 鍵不存在返回None
print("地址:", student.get("address", "未知")) # 提供默認值
# 添加和修改鍵值對
student["gender"] = "男" # 添加新鍵值對
print("添加性別後:", student)
student["age"] = 21 # 修改已有鍵值對
print("修改年齡後:", student)
# 刪除鍵值對
del student["score"] # 使用del語句刪除
print("刪除成績後:", student)
age = student.pop("age") # 使用pop()方法刪除並返回值
print(f"彈出的年齡: {age}")
print("彈出年齡後:", student)
last_item = student.popitem() # 彈出最後添加的鍵值對
print(f"彈出的最後項: {last_item}")
print("彈出最後項後:", student)
# 清空字典
student.clear()
print("清空後:", student)
輸出結果:
原始字典: {'name': '張三', 'age': 20, 'score': 95}
姓名: 張三
年齡: 20
地址: None
地址: 未知
添加性別後: {'name': '張三', 'age': 20, 'score': 95, 'gender': '男'}
修改年齡後: {'name': '張三', 'age': 21, 'score': 95, 'gender': '男'}
刪除成績後: {'name': '張三', 'age': 21, 'gender': '男'}
彈出的年齡: 21
彈出年齡後: {'name': '張三', 'gender': '男'}
彈出的最後項: ('gender', '男')
彈出最後項後: {'name': '張三'}
清空後: {}
4.4.2 字典的遍歷¶
# 字典遍歷示例
student = {
"name": "張三",
"age": 20,
"gender": "男",
"score": {"math": 95, "english": 88, "physics": 92}
}
# 遍歷鍵
print("遍歷鍵:")
for key in student.keys():
print(f" - {key}")
# 直接遍歷字典(默認遍歷鍵)
print("\n直接遍歷字典:")
for key in student:
print(f" - {key}")
# 遍歷值
print("\n遍歷值:")
for value in student.values():
print(f" - {value}")
# 遍歷鍵值對
print("\n遍歷鍵值對:")
for key, value in student.items():
print(f" - {key}: {value}")
# 嵌套字典遍歷
print("\n遍歷嵌套字典:")
for subject, score in student["score"].items():
print(f" - {subject}: {score}")
# 字典遍歷的最佳實踐
print("\n帶索引的遍歷:")
for i, (key, value) in enumerate(student.items()):
print(f" {i+1}. {key}: {value}")
輸出結果:
遍歷鍵:
- name
- age
- gender
- score
直接遍歷字典:
- name
- age
- gender
- score
遍歷值:
- 張三
- 20
- 男
- {'math': 95, 'english': 88, 'physics': 92}
遍歷鍵值對:
- name: 張三
- age: 20
- gender: 男
- score: {'math': 95, 'english': 88, 'physics': 92}
遍歷嵌套字典:
- math: 95
- english: 88
- physics: 92
帶索引的遍歷:
1. name: 張三
2. age: 20
3. gender: 男
4. score: {'math': 95, 'english': 88, 'physics': 92}
4.4.3 字典推導式¶
字典推導式是一種簡潔創建字典的方式,類似於列表推導式。
# 字典推導式示例
# 基本語法
squares = {x: x**2 for x in range(6)}
print("平方數字典:", squares)
# 條件過濾
even_squares = {x: x**2 for x in range(10) if x % 2 == 0}
print("偶數平方字典:", even_squares)
# 從現有字典創建新字典
prices = {"apple": 5, "banana": 3, "orange": 4, "grape": 8}
discounted = {item: price * 0.8 for item, price in prices.items()}
print("原價格:", prices)
print("打折後價格:", discounted)
# 使用兩個列表創建字典
fruits = ["apple", "banana", "orange"]
counts = [10, 15, 8]
fruit_inventory = {fruit: count for fruit, count in zip(fruits, counts)}
print("水果庫存:", fruit_inventory)
# 鍵值交換
original = {"a": 1, "b": 2, "c": 3}
swapped = {value: key for key, value in original.items()}
print("原字典:", original)
print("鍵值交換後:", swapped)
# 嵌套字典推導式
matrix = {
"A": [1, 2, 3],
"B": [4, 5, 6],
"C": [7, 8, 9]
}
flattened = {f"{key}{i+1}": value for key, values in matrix.items() for i, value in enumerate(values)}
print("嵌套列表字典:", matrix)
print("扁平化後:", flattened)
輸出結果:
平方數字典: {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
偶數平方字典: {0: 0, 2: 4, 4: 16, 6: 36, 8: 64}
原價格: {'apple': 5, 'banana': 3, 'orange': 4, 'grape': 8}
打折後價格: {'apple': 4.0, 'banana': 2.4, 'orange': 3.2, 'grape': 6.4}
水果庫存: {'apple': 10, 'banana': 15, 'orange': 8}
原字典: {'a': 1, 'b': 2, 'c': 3}
鍵值交換後: {1: 'a', 2: 'b', 3: 'c'}
嵌套列表字典: {'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9]}
扁平化後: {'A1': 1, 'A2': 2, 'A3': 3, 'B1': 4, 'B2': 5, 'B3': 6, 'C1': 7, 'C2': 8, 'C3': 9}
4.5 集合(Set)¶
集合是Python中的無序可變數據結構,用於存儲唯一的元素。集合中的元素不能重複,且必須是可哈希的(不可變類型)。
4.5.1 集合的基本操作¶
集合的定義與特點¶
集合具有以下特點:
- 無序:元素沒有固定的位置或順序
- 唯一:不允許重複元素
- 可變:可以添加或刪除元素
- 元素必須可哈希:只能包含不可變類型(字符串、數字、元組等)
- 不支持索引和切片:因爲是無序的
# 集合的創建方法示例
# 花括號創建
fruits = {"apple", "banana", "orange", "apple"} # 重複元素會被自動去除
empty_set = set() # 空集合(注意:{}創建的是空字典,不是空集合)
# set()構造函數
numbers = set([1, 2, 3, 2, 1]) # 從列表創建,自動去重
chars = set("hello") # 從字符串創建,每個字符作爲一個元素
# 集合推導式
squares = {x**2 for x in range(10) if x % 2 == 0} # 創建偶數的平方集合
print("水果集合:", fruits)
print("空集合:", empty_set)
print("數字集合:", numbers)
print("字符集合:", chars) # 注意順序是無法預測的
print("平方集合:", squares)
print("集合類型:", type(fruits))
輸出結果:
水果集合: {'orange', 'apple', 'banana'}
空集合: set()
數字集合: {1, 2, 3}
字符集合: {'e', 'o', 'h', 'l'}
平方集合: {0, 4, 16, 36, 64}
集合類型: <class 'set'>
集合的基本操作¶
# 集合基本操作示例
fruits = {"apple", "banana", "orange"}
print("原始集合:", fruits)
# 添加元素
fruits.add("grape") # 添加單個元素
print("添加grape後:", fruits)
fruits.update(["pear", "melon"]) # 添加多個元素
print("更新後:", fruits)
# 刪除元素
fruits.remove("banana") # 刪除指定元素,如果元素不存在會引發KeyError
print("刪除banana後:", fruits)
fruits.discard("kiwi") # 刪除指定元素,如果元素不存在不會引發錯誤
print("嘗試刪除不存在元素後:", fruits)
popped = fruits.pop() # 隨機移除一個元素並返回
print(f"彈出的元素: {popped}")
print("彈出元素後:", fruits)
fruits.clear() # 清空集合
print("清空後:", fruits)
# 成員檢測
vegetables = {"carrot", "potato", "tomato"}
print("\n蔬菜集合:", vegetables)
print("'potato'在集合中:", "potato" in vegetables)
print("'apple'不在集合中:", "apple" not in vegetables)
輸出結果:
原始集合: {'orange', 'apple', 'banana'}
添加grape後: {'orange', 'apple', 'banana', 'grape'}
更新後: {'pear', 'orange', 'melon', 'apple', 'banana', 'grape'}
刪除banana後: {'pear', 'orange', 'melon', 'apple', 'grape'}
嘗試刪除不存在元素後: {'pear', 'orange', 'melon', 'apple', 'grape'}
彈出的元素: pear
彈出元素後: {'orange', 'melon', 'apple', 'grape'}
清空後: set()
蔬菜集合: {'tomato', 'potato', 'carrot'}
'potato'在集合中: True
'apple'不在集合中: True
4.5.2 集合的數學操作¶
集合類型實現了數學中集合的概念,支持並集、交集、差集等操作。
# 集合數學操作示例
A = {1, 2, 3, 4, 5}
B = {4, 5, 6, 7, 8}
print("集合A:", A)
print("集合B:", B)
# 並集(兩個集合中的所有元素)
union1 = A.union(B) # 使用union()方法
union2 = A | B # 使用|運算符
print("並集 (A ∪ B):", union1)
print("並集 (A | B):", union2)
# 交集(兩個集合共有的元素)
intersection1 = A.intersection(B) # 使用intersection()方法
intersection2 = A & B # 使用&運算符
print("交集 (A ∩ B):", intersection1)
print("交集 (A & B):", intersection2)
# 差集(在A中但不在B中的元素)
difference1 = A.difference(B) # 使用difference()方法
difference2 = A - B # 使用-運算符
print("差集 (A - B):", difference1)
print("差集 (A - B):", difference2)
# 對稱差集(在A或B中,但不同時在兩者中的元素)
sym_diff1 = A.symmetric_difference(B) # 使用symmetric_difference()方法
sym_diff2 = A ^ B # 使用^運算符
print("對稱差集 (A △ B):", sym_diff1)
print("對稱差集 (A ^ B):", sym_diff2)
# 子集與超集
C = {1, 2}
D = {1, 2, 3, 4, 5, 6}
print("\n集合C:", C)
print("集合D:", D)
# 檢查子集
print("C是A的子集:", C.issubset(A))
print("C是A的子集:", C <= A)
print("C是A的真子集:", C < A) # 真子集意味着C是A的子集且C不等於A
# 檢查超集
print("D是B的超集:", D.issuperset(B))
print("D是B的超集:", D >= B)
print("D是B的真超集:", D > B) # 真超集意味着D是B的超集且D不等於B
# 檢查兩個集合是否沒有共同元素
E = {1, 2, 3}
F = {4, 5, 6}
print("\n集合E:", E)
print("集合F:", F)
print("E和F是否不相交:", E.isdisjoint(F)) # 如果沒有共同元素,返回True
輸出結果:
集合A: {1, 2, 3, 4, 5}
集合B: {4, 5, 6, 7, 8}
並集 (A ∪ B): {1, 2, 3, 4, 5, 6, 7, 8}
並集 (A | B): {1, 2, 3, 4, 5, 6, 7, 8}
交集 (A ∩ B): {4, 5}
交集 (A & B): {4, 5}
差集 (A - B): {1, 2, 3}
差集 (A - B): {1, 2, 3}
對稱差集 (A △ B): {1, 2, 3, 6, 7, 8}
對稱差集 (A ^ B): {1, 2, 3, 6, 7, 8}
集合C: {1, 2}
集合D: {1, 2, 3, 4, 5, 6}
C是A的子集: True
C是A的子集: True
C是A的真子集: True
D是B的超集: True
D是B的超集: True
D是B的真超集: True
集合E: {1, 2, 3}
集合F: {4, 5, 6}
E和F是否不相交: True
集合的實際應用¶
# 集合的實際應用示例
# 1. 去除列表中的重複元素
duplicates = [1, 2, 3, 1, 2, 5, 6, 7, 8, 8, 1]
unique_list = list(set(duplicates))
print("原列表:", duplicates)
print("去重後:", unique_list)
# 2. 查找共同元素
users_a = {"Alice", "Bob", "Charlie", "David"}
users_b = {"Charlie", "Eve", "Frank", "David"}
common_users = users_a & users_b
print("\n用戶組A:", users_a)
print("用戶組B:", users_b)
print("共同用戶:", common_users)
# 3. 查找唯一元素
only_in_a = users_a - users_b
only_in_b = users_b - users_a
print("只在A中的用戶:", only_in_a)
print("只在B中的用戶:", only_in_b)
# 4. 檢查兩個字符串是否使用相同字符
str1 = "listen"
str2 = "silent"
print(f"\n{str1}和{str2}使用相同字符集:", set(str1) == set(str2))
# 5. 統計文本中的唯一單詞數
text = "to be or not to be that is the question"
unique_words = set(text.split())
print("\n文本:", text)
print("唯一單詞數:", len(unique_words))
print("唯一單詞:", unique_words)
輸出結果:
原列表: [1, 2, 3, 1, 2, 5, 6, 7, 8, 8, 1]
去重後: [1, 2, 3, 5, 6, 7, 8]
用戶組A: {'Charlie', 'Alice', 'David', 'Bob'}
用戶組B: {'Charlie', 'Eve', 'David', 'Frank'}
共同用戶: {'Charlie', 'David'}
只在A中的用戶: {'Alice', 'Bob'}
只在B中的用戶: {'Eve', 'Frank'}
listen和silent使用相同字符集: True
文本: to be or not to be that is the question
唯一單詞數: 8
唯一單詞: {'that', 'not', 'question', 'or', 'the', 'is', 'to', 'be'}
4.6 數據結構的選擇與應用¶
在Python編程中,選擇合適的數據結構對於程序的效率和可讀性至關重要。本節將對前面介紹的數據結構進行對比,並提供選擇指南。
4.6.1 各種數據結構的特點對比¶
下面是Python主要數據結構的特點對比:
# 數據結構特點對比示例
import sys
# 創建各種數據結構並比較
test_str = "Python"
test_list = ["P", "y", "t", "h", "o", "n"]
test_tuple = ("P", "y", "t", "h", "o", "n")
test_dict = {"P": 1, "y": 2, "t": 3, "h": 4, "o": 5, "n": 6}
test_set = {"P", "y", "t", "h", "o", "n"}
# 比較內存佔用
print("內存佔用比較:")
print(f"字符串: {sys.getsizeof(test_str)} 字節")
print(f"列表: {sys.getsizeof(test_list)} 字節")
print(f"元組: {sys.getsizeof(test_tuple)} 字節")
print(f"字典: {sys.getsizeof(test_dict)} 字節")
print(f"集合: {sys.getsizeof(test_set)} 字節")
# 特性對比表格
print("\n數據結構特性對比:")
print("-" * 70)
print(f"{'特性':<15}{'字符串':<12}{'列表':<12}{'元組':<12}{'字典':<12}{'集合':<12}")
print("-" * 70)
print(f"{'可變性':<15}{'不可變':<12}{'可變':<12}{'不可變':<12}{'可變':<12}{'可變':<12}")
print(f"{'有序性':<15}{'有序':<12}{'有序':<12}{'有序':<12}{'有序*':<12}{'無序':<12}")
print(f"{'索引訪問':<15}{'支持':<12}{'支持':<12}{'支持':<12}{'鍵訪問':<12}{'不支持':<12}")
print(f"{'重複元素':<15}{'允許':<12}{'允許':<12}{'允許':<12}{'鍵唯一':<12}{'不允許':<12}")
print(f"{'異構元素':<15}{'字符':<12}{'任意類型':<12}{'任意類型':<12}{'鍵值對':<12}{'可哈希類型':<12}")
print("-" * 70)
print("* Python 3.7+中字典保持插入順序")
輸出結果:
內存佔用比較:
字符串: 55 字節
列表: 120 字節
元組: 88 字節
字典: 232 字節
集合: 216 字節
數據結構特性對比:
----------------------------------------------------------------------
特性 字符串 列表 元組 字典 集合
----------------------------------------------------------------------
可變性 不可變 可變 不可變 可變 可變
有序性 有序 有序 有序 有序* 無序
索引訪問 支持 支持 支持 鍵訪問 不支持
重複元素 允許 允許 允許 鍵唯一 不允許
異構元素 字符 任意類型 任意類型 鍵值對 可哈希類型
----------------------------------------------------------------------
* Python 3.7+中字典保持插入順序
4.6.2 不同場景下的數據結構選擇¶
# 不同場景的數據結構選擇示例
# 1. 需要有序數據時
print("有序數據場景:")
# 使用列表存儲學生成績並保持順序
scores = [85, 92, 78, 90, 88]
print(f"原始成績: {scores}")
scores.sort()
print(f"排序後成績: {scores}")
# 使用元組存儲不可變的座標點
point = (10, 20)
print(f"座標點: {point}")
# 2. 需要快速查找時
print("\n快速查找場景:")
# 使用字典存儲學生信息,通過學號快速查找
students = {
"1001": {"name": "張三", "age": 20, "major": "計算機科學"},
"1002": {"name": "李四", "age": 21, "major": "數學"},
"1003": {"name": "王五", "age": 22, "major": "物理"}
}
print(f"查找學號1002的學生: {students['1002']['name']}")
# 使用集合進行快速成員檢測
allowed_users = {"admin", "manager", "editor"}
user = "editor"
print(f"用戶'{user}'是否有權限: {user in allowed_users}")
# 3. 需要唯一元素時
print("\n唯一元素場景:")
# 使用集合去除重複元素
visitor_ips = ["192.168.1.1", "192.168.1.2", "192.168.1.1",
"192.168.1.3", "192.168.1.2", "192.168.1.4"]
unique_ips = set(visitor_ips)
print(f"原始IP列表: {visitor_ips}")
print(f"唯一IP數量: {len(unique_ips)}")
print(f"唯一IP列表: {unique_ips}")
# 4. 需要鍵值對映射時
print("\n鍵值對映射場景:")
# 使用字典存儲配置信息
config = {
"host": "localhost",
"port": 8080,
"debug": True,
"max_connections": 100
}
print(f"服務器配置: {config}")
print(f"服務器端口: {config['port']}")
# 使用字典計數
words = ["apple", "banana", "apple", "orange", "banana", "apple"]
word_count = {}
for word in words:
if word in word_count:
word_count[word] += 1
else:
word_count[word] = 1
print(f"單詞列表: {words}")
print(f"單詞計數: {word_count}")
輸出結果:
有序數據場景:
原始成績: [85, 92, 78, 90, 88]
排序後成績: [78, 85, 88, 90, 92]
座標點: (10, 20)
快速查找場景:
查找學號1002的學生: 李四
用戶'editor'是否有權限: True
唯一元素場景:
原始IP列表: ['192.168.1.1', '192.168.1.2', '192.168.1.1', '192.168.1.3', '192.168.1.2', '192.168.1.4']
唯一IP數量: 4
唯一IP列表: {'192.168.1.2', '192.168.1.3', '192.168.1.1', '192.168.1.4'}
鍵值對映射場景:
服務器配置: {'host': 'localhost', 'port': 8080, 'debug': True, 'max_connections': 100}
服務器端口: 8080
單詞列表: ['apple', 'banana', 'apple', 'orange', 'banana', 'apple']
單詞計數: {'apple': 3, 'banana': 2, 'orange': 1}
4.6.3 性能考量¶
在選擇數據結構時,需要考慮操作的時間複雜度和空間複雜度。
# 性能考量示例
import time
import random
# 準備測試數據
small_list = list(range(1000))
random.shuffle(small_list)
small_set = set(small_list)
small_dict = {i: i for i in small_list}
# 測試查找性能
print("查找性能測試:")
# 列表查找
start = time.time()
for _ in range(1000):
500 in small_list
list_time = time.time() - start
print(f"列表查找耗時: {list_time:.6f}秒")
# 集合查找
start = time.time()
for _ in range(1000):
500 in small_set
set_time = time.time() - start
print(f"集合查找耗時: {set_time:.6f}秒")
# 字典查找
start = time.time()
for _ in range(1000):
500 in small_dict
dict_time = time.time() - start
print(f"字典查找耗時: {dict_time:.6f}秒")
print(f"集合比列表快: {list_time/set_time:.1f}倍")
print(f"字典比列表快: {list_time/dict_time:.1f}倍")
# 常見操作的時間複雜度
print("\n常見操作的時間複雜度:")
print("-" * 70)
print(f"{'操作':<20}{'列表':<15}{'元組':<15}{'字典':<15}{'集合':<15}")
print("-" * 70)
print(f"{'訪問元素':<20}{'O(1)':<15}{'O(1)':<15}{'O(1)':<15}{'N/A':<15}")
print(f"{'搜索元素':<20}{'O(n)':<15}{'O(n)':<15}{'O(1)':<15}{'O(1)':<15}")
print(f"{'插入元素':<20}{'O(1)/O(n)*':<15}{'N/A':<15}{'O(1)':<15}{'O(1)':<15}")
print(f"{'刪除元素':<20}{'O(1)/O(n)*':<15}{'N/A':<15}{'O(1)':<15}{'O(1)':<15}")
print("-" * 70)
print("* 列表在末尾操作是O(1),在開頭或中間操作是O(n)")
輸出結果(實際運行時間可能有所不同):
查找性能測試:
列表查找耗時: 0.023438秒
集合查找耗時: 0.000998秒
字典查找耗時: 0.000999秒
集合比列表快: 23.5倍
字典比列表快: 23.5倍
常見操作的時間複雜度:
----------------------------------------------------------------------
操作 列表 元組 字典 集合
----------------------------------------------------------------------
訪問元素 O(1) O(1) O(1) N/A
搜索元素 O(n) O(n) O(1) O(1)
插入元素 O(1)/O(n)* N/A O(1) O(1)
刪除元素 O(1)/O(n)* N/A O(1) O(1)
----------------------------------------------------------------------
* 列表在末尾操作是O(1),在開頭或中間操作是O(n)
4.6.4 實際應用案例¶
# 實際應用案例示例
# 案例1: 數據分析 - 統計文本中單詞頻率
def word_frequency_analysis(text):
"""分析文本中單詞出現的頻率"""
# 將文本轉換爲小寫並分割成單詞
words = text.lower().split()
# 使用字典統計頻率
frequency = {}
for word in words:
# 去除標點符號
word = word.strip('.,!?;:()"\'')
if word:
frequency[word] = frequency.get(word, 0) + 1
# 按頻率排序
sorted_freq = sorted(frequency.items(), key=lambda x: x[1], reverse=True)
return sorted_freq
# 示例文本
sample_text = """Python is a programming language that lets you work quickly and integrate systems more effectively.
Python is powerful and fast, plays well with others, runs everywhere, is friendly and easy to learn."""
print("案例1: 文本單詞頻率分析")
word_freq = word_frequency_analysis(sample_text)
print("前5個高頻單詞:")
for word, count in word_freq[:5]:
print(f" {word}: {count}次")
# 案例2: 數據去重與合併 - 合併用戶數據
def merge_user_data(user_lists):
"""合併多個用戶列表並去除重複"""
# 使用集合去重
all_users = set()
for user_list in user_lists:
all_users.update(user_list)
# 轉回列表並排序
return sorted(list(all_users))
# 示例用戶數據
users_site_a = ["user1", "user2", "user3", "user4"]
users_site_b = ["user2", "user3", "user5", "user6"]
users_site_c = ["user1", "user6", "user7"]
print("\n案例2: 用戶數據合併與去重")
merged_users = merge_user_data([users_site_a, users_site_b, users_site_c])
print(f"站點A用戶: {users_site_a}")
print(f"站點B用戶: {users_site_b}")
print(f"站點C用戶: {users_site_c}")
print(f"合併後的唯一用戶: {merged_users}")
print(f"唯一用戶總數: {len(merged_users)}")
# 案例3: 數據結構組合 - 簡單購物車系統
class ShoppingCart:
"""簡單購物車系統"""
def __init__(self):
# 使用字典存儲商品及數量
self.items = {}
def add_item(self, item_id, name, price, quantity=1):
"""添加商品到購物車"""
if item_id in self.items:
# 更新現有商品數量
self.items[item_id]["quantity"] += quantity
else:
# 添加新商品
self.items[item_id] = {
"name": name,
"price": price,
"quantity": quantity
}
def remove_item(self, item_id, quantity=None):
"""從購物車移除商品"""
if item_id not in self.items:
return False
if quantity is None or quantity >= self.items[item_id]["quantity"]:
# 完全移除商品
del self.items[item_id]
else:
# 減少商品數量
self.items[item_id]["quantity"] -= quantity
return True
def get_total(self):
"""計算購物車總價"""
return sum(item["price"] * item["quantity"] for item in self.items.values())
def get_item_count(self):
"""獲取購物車中商品總數"""
return sum(item["quantity"] for item in self.items.values())
def __str__(self):
"""購物車字符串表示"""
if not self.items:
return "購物車爲空"
cart_str = "購物車內容:\n"
cart_str += "-" * 50 + "\n"
cart_str += f"{'商品名稱':<20}{'單價':<10}{'數量':<10}{'小計':<10}\n"
cart_str += "-" * 50 + "\n"
for item in self.items.values():
subtotal = item["price"] * item["quantity"]
cart_str += f"{item['name']:<20}{item['price']:<10}{item['quantity']:<10}{subtotal:<10.2f}\n"
cart_str += "-" * 50 + "\n"
cart_str += f"總計: {self.get_total():.2f} 元 ({self.get_item_count()} 件商品)"
return cart_str
print("\n案例3: 購物車系統")
cart = ShoppingCart()
cart.add_item("p001", "Python編程入門", 79.0, 1)
cart.add_item("p002", "數據結構與算法", 85.5, 2)
cart.add_item("p003", "Web開發實戰", 95.0, 1)
print(cart)
print("\n移除一本'數據結構與算法'...")
cart.remove_item("p002", 1)
print(cart)
輸出結果:
案例1: 文本單詞頻率分析
前5個高頻單詞:
and: 4次
is: 3次
python: 2次
to: 2次
you: 1次
案例2: 用戶數據合併與去重
站點A用戶: ['user1', 'user2', 'user3', 'user4']
站點B用戶: ['user2', 'user3', 'user5', 'user6']
站點C用戶: ['user1', 'user6', 'user7']
合併後的唯一用戶: ['user1', 'user2', 'user3', 'user4', 'user5', 'user6', 'user7']
唯一用戶總數: 7
案例3: 購物車系統
購物車內容:
--------------------------------------------------
商品名稱 單價 數量 小計
--------------------------------------------------
Python編程入門 79.0 1 79.0
數據結構與算法 85.5 2 171.0
Web開發實戰 95.0 1 95.0
--------------------------------------------------
總計: 345.00 元 (4 件商品)
移除一本'數據結構與算法'...
購物車內容:
--------------------------------------------------
商品名稱 單價 數量 小計
--------------------------------------------------
Python編程入門 79.0 1 79.0
數據結構與算法 85.5 1 85.5
Web開發實戰 95.0 1 95.0
--------------------------------------------------
總計: 259.50 元 (3 件商品)
總結¶
本章詳細介紹了Python中的五種主要數據結構:字符串、列表、元組、字典和集合。每種數據結構都有其獨特的特點和適用場景:
- 字符串:適用於文本處理,提供了豐富的字符串操作方法。
- 列表:適用於存儲有序、可變的元素序列,支持各種操作和修改。
- 元組:適用於存儲不可變的有序元素序列,可作爲字典鍵或確保數據不被修改。
- 字典:適用於鍵值對映射,提供高效的查找和存儲。
- 集合:適用於存儲唯一元素,支持集合運算,高效的成員檢測。
選擇合適的數據結構應考慮:
- 數據的性質(有序/無序、可變/不可變)
- 需要執行的操作(訪問、搜索、插入、刪除)
- 性能要求(時間和空間複雜度)
- 代碼可讀性和維護性
掌握這些數據結構及其適用場景,將幫助你編寫更高效、更優雅的Python代碼。