02 - 基本資料型態(Data Types)

01-什麼是Python | 下一篇 → 03-控制流程


變數(Variable)

# 直接賦值,不需要宣告型別
name = "DirtyWolf"    # 字串
age = 25              # 整數
height = 1.75         # 浮點數
is_doctor = True      # 布林值
 
# 查看型別
print(type(name))    # <class 'str'>

數字型態

int(整數)

x = 10
y = -3
z = 1_000_000    # 底線可提高可讀性
 
# 運算
print(10 + 3)    # 13
print(10 - 3)    # 7
print(10 * 3)    # 30
print(10 / 3)    # 3.3333...(浮點除法)
print(10 // 3)   # 3(整數除法)
print(10 % 3)    # 1(餘數)
print(2 ** 10)   # 1024(次方)

float(浮點數)

pi = 3.14159
e = 2.71828
 
# 四捨五入
round(3.14159, 2)    # 3.14

字串(str)

s1 = "Hello"
s2 = 'World'
s3 = """多行
字串"""
 
# 常用操作
print(len(s1))           # 5(長度)
print(s1.upper())        # HELLO
print(s1.lower())        # hello
print(s1 + " " + s2)    # Hello World(串接)
print(s1 * 3)            # HelloHelloHello(重複)
print(s1[0])             # H(索引)
print(s1[1:3])           # el(切片)
 
# f-string(格式化,Python 3.6+,推薦)
name = "Andrew"
age = 28
print(f"我叫 {name},今年 {age} 歲")

f-string 進階用法(很實用,務必熟)

pi = 3.14159
score = 0.8732
n = 1234567
 
print(f"{pi:.2f}")        # 3.14(小數點後 2 位)
print(f"{score:.1%}")     # 87.3%(轉百分比)
print(f"{n:,}")           # 1,234,567(千分位逗號)
print(f"{42:05d}")        # 00042(補零到 5 位,常用在檔名 001.png)
print(f"{'hi':>10}")      # '        hi'(靠右對齊,寬度 10)
print(f"{'hi':<10}|")     # 'hi        |'(靠左對齊)
print(f"{'hi':^10}")      # '    hi    '(置中)
 
# = 自帶「變數名=值」,debug 神器(Python 3.8+)
x = 10
print(f"{x=}")            # x=10
 
# 大括號裡可放任何表達式
items = ["a", "b", "c"]
print(f"共有 {len(items)} 項")   # 共有 3 項

布林(bool)

is_valid = True
is_empty = False
 
# 比較運算
print(5 > 3)     # True
print(5 == 5)    # True
print(5 != 3)    # True
 
# 邏輯運算
print(True and False)    # False
print(True or False)     # True
print(not True)          # False

串列(list)

有序、可修改的集合:

fruits = ["apple", "banana", "cherry"]
 
# 存取
print(fruits[0])     # apple
print(fruits[-1])    # cherry(最後一個)
 
# 修改
fruits.append("mango")      # 新增到末尾
fruits.insert(1, "grape")   # 插入到指定位置
fruits.remove("banana")     # 刪除指定值
fruits.pop()                # 刪除最後一個
 
# 切片
print(fruits[1:3])   # 取第 2 到第 3 個元素
 
# 長度
print(len(fruits))

List Comprehension(清單生成式)

把「建立空 list → for 迴圈 → append」濃縮成一行,是 Python 最常用的特色語法:

# 一般寫法
squares = []
for i in range(10):
    squares.append(i ** 2)
 
# Comprehension(等同上面,更精簡)
squares = [i ** 2 for i in range(10)]
 
# 加條件篩選(只留偶數的平方)
even_squares = [i ** 2 for i in range(10) if i % 2 == 0]
 
# 對既有 list 做轉換
names = ["andrew", "bob", "cathy"]
upper = [n.upper() for n in names]        # ['ANDREW', 'BOB', 'CATHY']
 
# 巢狀(攤平二維 list)
matrix = [[1, 2], [3, 4]]
flat = [x for row in matrix for x in row]  # [1, 2, 3, 4]

一行寫不下、或邏輯太複雜時,回去用普通 for 迴圈反而更好讀。可讀性 > 炫技。


字典(dict)

Key-Value 對的集合:

person = {
    "name": "Andrew",
    "age": 28,
    "job": "doctor"
}
 
# 存取
print(person["name"])         # Andrew
print(person.get("age"))      # 28(推薦,不會報錯)
 
# 修改/新增
person["age"] = 29
person["city"] = "Taipei"
 
# 刪除
del person["job"]
 
# 遍歷
for key, value in person.items():
    print(f"{key}: {value}")

Dict Comprehension(字典生成式)

# 從兩個 list 組字典
names = ["a", "b", "c"]
scores = [90, 80, 70]
result = {n: s for n, s in zip(names, scores)}   # {'a': 90, 'b': 80, 'c': 70}
 
# 篩選 + 轉換(只留及格的,並 *2)
passed = {k: v * 2 for k, v in result.items() if v >= 80}
 
# 反轉 key 與 value
person = {"name": "Andrew", "city": "Taipei"}
inverted = {v: k for k, v in person.items()}

元組(tuple)

有序、不可修改的集合:

coordinates = (25.05, 121.53)
print(coordinates[0])    # 25.05
 
# 常見用途:函式回傳多個值
def get_size():
    return 1920, 1080    # 其實是 tuple
 
width, height = get_size()

集合(set)

不重複元素的集合:

tags = {"python", "coding", "python"}    # 重複會自動去掉
print(tags)    # {'python', 'coding'}
 
tags.add("obsidian")
tags.discard("coding")

型別轉換

int("42")        # str → int:42
float("3.14")    # str → float:3.14
str(100)         # int → str:"100"
list("hello")    # str → list:['h', 'e', 'l', 'l', 'o']

⚠️ 常見初學陷阱

這幾個是初學者最常踩的雷,看懂它們能省下大量 debug 時間。

1. == vs is

  • ==:比較是否相等(你通常要的是這個)。
  • is:比較是否為同一個物件(記憶體位置相同)。
a = [1, 2, 3]
b = [1, 2, 3]
print(a == b)    # True(值一樣)
print(a is b)    # False(是兩個不同的 list)
 
c = a
print(a is c)    # True(c 只是 a 的別名,指向同一物件)

判斷 None 才用 is:寫 if x is None:,不要寫 if x == None:

字串/數字的相等請一律用 ==is 對小整數/短字串「碰巧」會 True 是實作細節,別依賴)。

2. 淺拷貝(shallow copy)vs 深拷貝(deep copy)

直接 b = a 不是複製,只是貼了一個標籤——改 b 等於改 a

a = [1, 2, 3]
b = a
b.append(4)
print(a)    # [1, 2, 3, 4]  ← a 也被改了!

要真正複製,用切片 a[:]list(a)a.copy()(這些都是淺拷貝):

a = [1, 2, 3]
b = a.copy()       # 或 a[:] / list(a)
b.append(4)
print(a)    # [1, 2, 3]    ← a 不受影響

淺拷貝只複製最外層;裡面若有巢狀 list/dict,內層仍是共用的:

a = [[1, 2], [3, 4]]
b = a.copy()
b[0].append(99)
print(a)    # [[1, 2, 99], [3, 4]]  ← 內層被改了!
 
# 需要連內層都獨立 → 用 copy.deepcopy
import copy
a = [[1, 2], [3, 4]]
b = copy.deepcopy(a)
b[0].append(99)
print(a)    # [[1, 2], [3, 4]]      ← 完全不受影響
寫法行為
b = a不複製,同一物件(別名)
a.copy() / a[:] / list(a)淺拷貝(外層獨立、內層共用)
copy.deepcopy(a)深拷貝(連內層都獨立)

這也是為什麼 dict 當參數傳進函式後,在函式裡改它會「外面也跟著變」——傳進去的是同一個物件。


01-什麼是Python | 下一篇 → 03-控制流程