回憶

  • 列表 賦值運算 兩種形式
  1. 將列表 直接 賦值
  • 造成兩個列表指向同一個對象
  • 一改全改
  1. 將 列表副本 賦給 變量
  • 這兩個列表變量指向不同的對象
  • 互不影響
clist1 = list("oeasy")
clist2 = clist1
clist2 = clist1.copy()

oeasy教python108 列表_加法_增強賦值_加等於_extend_擴展列表 _字符串

  • 列表 能相加 嗎?🤔
lst1 + lst2

回憶字符串

  • 字符串可以進行
  • 加法
  • 乘法
"動詞打次" + "東東打次"
"動詞打次" * 3 + "東東打次"
("動詞打次" * 3 + "東東打次") * 4
  • 字符串加法
  • 有啥應用 嗎?

四大名著大亂燉

oeasy教python108 列表_加法_增強賦值_加等於_extend_擴展列表 _賦值_02

import random

# 從四大名著中分別提取角色和事蹟
# 《西遊記》
journey_to_the_west_characters = ["孫悟空", "唐僧", "沙僧"]
journey_to_the_west_stories = ["大鬧天宮", "三打白骨精", "真假美猴王"]

# 《紅樓夢》
dream_of_the_red_chamber_characters = ["林黛玉", "賈寶玉", "薛寶釵"]
dream_of_the_red_chamber_stories = ["黛玉葬花", "寶玉捱打", "寶釵撲蝶"]

# 《三國演義》
romance_of_the_three_kingdoms_characters = ["劉備", "關羽", "諸葛亮"]
romance_of_the_three_kingdoms_stories = ["桃園結義", "草船借箭", "空城計"]

# 《水滸傳》
water_margin_characters = ["宋江", "武松", "魯智深"]
water_margin_stories = ["怒殺閻婆惜", "景陽岡打虎", "倒拔垂楊柳"]

# 彙總角色列表
all_characters = journey_to_the_west_characters + \
                 dream_of_the_red_chamber_characters + \
                 romance_of_the_three_kingdoms_characters + \
                 water_margin_characters

# 彙總事蹟列表
all_stories = journey_to_the_west_stories + \
              dream_of_the_red_chamber_stories + \
              romance_of_the_three_kingdoms_stories + \
              water_margin_stories

# 隨機搭配角色和事蹟
random_character = random.choice(all_characters)
random_story = random.choice(all_stories)

print(f"{random_character}——{random_story}")

結果

oeasy教python108 列表_加法_增強賦值_加等於_extend_擴展列表 _賦值_03

  • 代碼中的反斜槓 是
  • 續航符
  • line-continuation character
# 彙總角色列表
all_characters = journey_to_the_west_characters + \
                 dream_of_the_red_chamber_characters + \
                 romance_of_the_three_kingdoms_characters + \
                 water_margin_characters
  • 可以避免 橫向滾動

列表加法

  • 數字列表
  • https://pythontutor.com/render.html#mode=display
lst1 = list(range(3))
print("lst1:", lst1)
lst2 = [3, 4, 5]
print("lst2:", lst2)
print("lst1 + lst2:", lst1 + lst2)
  • 數字列表
  • 可以相加

oeasy教python108 列表_加法_增強賦值_加等於_extend_擴展列表 _垃圾回收_04

  • 字符串列表
  • 可以 相加 嗎?

加法運算

  • 字符串列表
  • 也是可以相加的
lst1 = list("oeasy")
lst2 = list("o2z")
print(lst1 + lst2)
  • 但是 相加的結果
  • 沒賦給 任何變量
  • 直接 就

oeasy教python108 列表_加法_增強賦值_加等於_extend_擴展列表 _賦值_05

  • 想 不讓他
  • 咋辦呢?

加完了賦值

  • 把加完的結果賦給 lst3
lst1 = list("oeasy")
lst2 = list("o2z")
lst3 = lst1 + lst2
  • 相加結果 有 變量名引用
  • 就不會 被 垃圾回收

oeasy教python108 列表_加法_增強賦值_加等於_extend_擴展列表 _垃圾回收_06

  • 什麼是垃圾回收呢?

垃圾回收

  • c語言
  • 手動 分配和釋放內存
  • 內存空間
  • 分配容易
  • 但 容易 忘記釋放
  • 結果
  • 佔用內存 越來愈多
  • 造成泄漏、崩潰

oeasy教python108 列表_加法_增強賦值_加等於_extend_擴展列表 _垃圾回收_07

  • python 等現代語言 解釋器
  • 定期觀察 已經分配的 內存空間
  • 是否 還有變量 在引用
  • getrefcount
  • 沒有引用的話
  • 就垃圾回收
  • garage collection
lst3 = lst1 + lst2
  • 把求和結果 賦給lst3
  • 就能存的住了
  • 如果 把 求和結果
  • 直接 賦給 lst1 呢?

將列表之和賦回給lst1

lst1 = list("oeasy")
lst2 = list("o2z")
lst1 = lst1 + lst2
  • 賦值成功

oeasy教python108 列表_加法_增強賦值_加等於_extend_擴展列表 _字符串_08

  • 能用 增強賦值 嗎?

增強賦值

增強賦值

是一種 賦值

在賦值之外 還有增強

  • += 就是 增強賦值運算
  • augmented assignment
lst1 = list("oeasy")
lst2 = list("o2z")
lst1 += lst2
  • lst1 += lst2
  • 相當於 lst1 = lst1 + lst2

oeasy教python108 列表_加法_增強賦值_加等於_extend_擴展列表 _賦值_09

  • 這倆完全一樣嗎?

增強賦值運算

  • 從求和結果來看
  • 兩者一致
lst1 = list("oeasy")
print("lst1:", id(lst1))
lst2 = list("o2z")
print("lst2:", id(lst2))
lst1 += lst2 
print("lst1:", id(lst1))
  • 增強賦值中 lst1 的 地址沒有變

oeasy教python108 列表_加法_增強賦值_加等於_extend_擴展列表 _賦值_10

  • 先求和 再賦值呢?

觀察

lst1 = list("oeasy")
print("lst1:", id(lst1))
lst2 = list("o2z")
print("lst2:", id(lst2))
lst1 = lst1 + lst2 
print("lst1:", id(lst1))
  • 從引用地址 來看
  • l1 使用 l1 + l2 的新地址
  • += 則會保留 l1 原來引用的地址

oeasy教python108 列表_加法_增強賦值_加等於_extend_擴展列表 _垃圾回收_11

  • 有啥區別嗎?

效率

效果 相同 - 但效率不同!

  • 加法運算 效率低
  • 過程是 新建一個列表
  • 然後把 lst1 的列表項都拿過來
  • 再把 lst2 的列表項都拿過來
  • 最後把相加結果 賦給lst1
  • 效率 不如
  • 增強賦值

oeasy教python108 列表_加法_增強賦值_加等於_extend_擴展列表 _垃圾回收_12

  • 增強賦值 就是
  • 用列表 擴充(extend)列表

extend

  • 列表還真有個成員方法
  • 就叫做 extend
lst1 = list("oeasy")
lst2 = list("o2z")
lst1.extend(lst2)
  • 確實能夠擴列
  • 擴展列表

oeasy教python108 列表_加法_增強賦值_加等於_extend_擴展列表 _字符串_13

  • 這個extend怎麼用?

查詢幫助

help(list.extend)
  • extend
  • 把參數裏面的列表
  • 循環地放到extend方法的主體後面

oeasy教python108 列表_加法_增強賦值_加等於_extend_擴展列表 _賦值_14

  • 將列表相加
  • lst1 = lst1 + lst2
  • 可以得到列表在 新地址
  • 有 2種方式 可以 擴充列表
  1. lst1 += lst2
  2. lst1.extend(l2)
  • extend(擴列) 和 append(追加)
  • 有什麼區別呢?

區別

num_list = [1, 2, 3]
print(num_list)
num_list.append([4, 5])
print(num_list)
num_list.remove([4, 5])
print(num_list)
num_list.extend([4, 5])
print(num_list)
  • 效果不同

oeasy教python108 列表_加法_增強賦值_加等於_extend_擴展列表 _賦值_15

對比

  • append
  • 添加是 列表項
  • 把列表作為元素 放到最後
  • extend
  • 擴展 原始列表
  • 把 新列表 對接到 原列表 尾巴上
  • 對應 加法賦值

oeasy教python108 列表_加法_增強賦值_加等於_extend_擴展列表 _賦值_16

對比項

append

extend

描述

添加的是列表項

擴展原始列表

特點

將元素作為整體添加到列表末尾

把新列表對接到原列表尾巴上,合併兩個列表

總結

  • 這次我們瞭解 列表加法
  1. 對 相加結果 賦值 - lst1 = lst1 + lst2 - 加法的本質 是 將兩個列表 拼接 - 並將 結果位置 賦給幀(frame)上的變量 來引用
  2. 對列表 進行擴充 - 3種做法
  1. lst1 += lst2
  2. lst1[-1:] = lst2
  3. lst1.extend(lst2)
  • 上述 2類方法 結果相同
  • 但是稍有區別
  1. 結果地址
  • 會改變l1地址
  • 後三種不改變地址
  1. 效率不同
  • 後三種效率高
  • 直接擴展列表

oeasy教python108 列表_加法_增強賦值_加等於_extend_擴展列表 _賦值_17

  • 既然 有 列表加法
  • 那有 列表乘法 嗎?🤔
  • 下次再説 👋