PYTHON

Lesson 3

string & list & set & dict

Lecturer: 立葉

list

what is list? 

串列!

     list的基本性質:

  • 可以儲存很多個變數;變數型態不同也沒關係
  • 可以擷取部分片段,也可以修改
  • 當然也是可迭代的(iterable)

宣告一個list

(1) 宣告空陣列:串列名 = []

(2) 宣告非空陣列:串列名=[變數1,變數2,...]

a = []
print(type(a))
# <class 'list'>

b = [1, 2, [3, 4]] #list裡面的list!

list.append()

新增一個變數進去串列

  • 可以在串列尾端塞一個值進去list
a = ["蘇昱亘", "阿蘇", "RE", "RepKiroNcA", "心結長"]
a.append("酥育根")
print(a)
#['蘇昱亘', '阿蘇', 'RE', 'RepKiroNcA', '心結長', '酥育根']

以迴圈賦值

  • 串列 = list(range(n))
  • 串列 = [ 一個運算式(?) for 疊代變數 in range() ]
a = list(range(10))
print(a)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

b = [i**3 for i in range(1, 6)]
print(b)
# [1, 8, 27, 64, 125]

這是上次課程的補釘,好欸

以迴圈賦值

  • 甚至給兩個變數也沒問題ㄉ
  • 當然也能用 if 來寫
a = [[i*j for i in range(1,6)] for j in range(2,7)]
print(a)
# [[2, 4, 6, 8, 10], [3, 6, 9, 12, 15], [4, 8, 12, 16, 20], [5, 10, 15, 20, 25], [6, 12, 18, 24, 30]]
a = [i**2 for i in range(1, 10) if i%2==0]
print(a)
# [4, 16, 36, 64]

list[n]取得串列的第n項

  • 從第0項開始數,所以實際上的第一項 index 值是0
  • 放負數的 index 代表由後數回來
  • 但如果想找的 index 太大會回傳 IndexError
a = ["蘇昱亘", "阿蘇", "RE", "RepKiroNcA", "心結長"]
print(a[0])
print(a[2])
print(a[-1])
# 蘇昱亘
# RE
# 心結長

list.index()

  • 可以找到括號內的值所在的 index!
  • 有多個值,則回傳最前面的
  • 找不到,則回傳 ValueError
a = ["蘇昱亘", "阿蘇", "RE", "RepKiroNcA", "心結長"]
print(a.index("RE")) #2
print(a.index(1)) #(ValueError)

slice

  • 可以使用[begin:end:step]來擷取部分串列
  • 像迴圈一樣
  • step可以是負數,代表倒著數回來
  • 預設是start=0, end=len(str), step=1
  • 不用的話空著就好
a = ["蘇昱亘", "阿蘇", "RE", "RepKiroNcA", "心結長"] 
print(a[0:5:1]) #['蘇昱亘', '阿蘇', 'RE', 'RepKiroNcA', '心結長']
print(a[1:]) #['阿蘇', 'RE', 'RepKiroNcA', '心結長']
print(a[:4]) #['蘇昱亘', '阿蘇', 'RE', 'RepKiroNcA']
print(a[4:2:-1]) #['心結長', 'RepKiroNcA']

list.pop()

刪除一個index的值

  • 如果()內不放東西,預設刪掉最後一項
a = [123, "abc", True]
a.pop(1)  #刪除a[1]那一項
print(a)
# [123, True]

list.remove()

刪除一個指定的值

  • 在list裡面找到()裡面的值並刪除
  • 有多個,則刪除最前面一項
  • 沒有找到,則回傳ValueError
c = ["no."]
c.remove("yes.")
# (程式出錯,回傳ValueError)
a = [123, "abc", True]
a.remove(123)
print(a)
# ['abc', True]

b = ['hi', 'hey', 'hi']
b.remove('hi')
print(b)
# ['hey', 'hi']

list.count()

尋找括號內的東西出現多少次

a = [22, 25, 29, 29, 25, 26]
print(a.count(29))
# 2

b = ["格列格里七世", "章程一"]
print(b.count("MR"))
# 0
# 好欸這樣程式不會回傳錯誤

使用for迴圈迭代串列

a = [123, 'abc', True]
for i in a:
  print(i)
# 123
# abc
# True
  • for 迭代變數 in 串列:
  • 下面可以寫自己想要執行程式

shallow copy

a = [123, 'abc', True]
b = a #a和b共用同個記憶體
b[0] = 456
#改的是串列b,但a也會一起被更改
print(a)
# [456, 'abc', True]
  • 只是把 a 的記憶體位址複製給 b
  • b 被修改等同於 a 被修改
  • 也就是類似 reference 的概念!

deep copy

a = [123, 'abc', True]
b = a[::] #a的值複製給b
b[0] = 456
#a不會被因此更改
print(a)
# [123, 'abc', True]
  • 完全複製了一個副本
  • a 和 b 的容器記憶體位址不同

string

what is string? 

字串!

     複習下string基本性質與注意事項:

  • 把一堆字元串起來!
  • 輸入時的預設變數型態
  • 如果程式碼內有字串內容,要以引號括起來!
  • str()可以將括號內的東西轉成字串型態
  • 可迭代、可修改
  • 想要複習格式化字串可以點我

字串運算

  •  用+連接多個字串
  •  用*連接一個字串,後面一個int
a = "abc"
b = "def"
c = "ghi"
print(a + b + c)
#abcdefghi
a = "abc"
print(a*3)
#abcabcabc

使用[]擷取字串

  • 字串就像是串列,我們可以使用[]來取得字串中指定的 index 的字元
a = "abcdefghigk"
print(a[0]) 
print(a[2])
print(a[-1]) #由後開始數
# a
# c
# k

[r:l:s]可以擷取字串片段

  • 格式:[start:end:step]
  • 跟 list 一樣
  • step 可以是負的,但記得 start > end
a = "abcdefghigk"
print(a[0:5:1]) #只會跑到a[4]
print(a[0:4:2])
print(a[10:5:-2])
# abcde
# ac
# kig

[r:l:s]可以擷取字串片段

  • 格式:[start:end:step]
  • 預設是start=0, end=len(str), step=1
  • 不用的話空著就好
a = "abcdefghigk"
print(a[0:5:1]) #只會跑到a[4]
print(a[0:4:2])
print(a[10:5:-2])
# abcde
# ac
# kig

len(str) 回傳字串長度

a = "greenhouse"
print(len(a))
# 10

str2 in str1

判斷 str2 是否為 str1 的片段!

a = "times1 dian greenhouse dian"
print("dian" in a)
# True
a = "times1 greenhouse"
print("dian" in a)
# False

str1.find(str2) 

在 str1 中尋找特定字串的 index!

a = "times1 dian greenhouse dian"
print(a.find("dian"))
#有兩個dian,回傳第一個dian中d所在的index
# 7
  • 如果 str1 中有 str2,則回傳第一個找到的 str2 首個字元在 str1 的 index!
a = "times1 greenhouse"
print(a.find("dian"))
# -1
  • 如果 str1 中沒有 str2,則回傳 -1

str1.count(str2) 

回傳 str2 在 str1 中出現的次數!

a = "abcabcabcabcabc"
print(a.count("abca"))
a = "times1 dian greenhouse dian"
print(a.count("dian"))
#2
  • 在 str1 中,對於每個字元,一旦該字元已經被 count 到了,那就不會再被數到一次了

str1.replace(str2, str3) 

把所有 str2 換成 str3!

a = "Aaron Su"
a = a.replace("S","W")
print(a)
# Aaron Wu

b = "abcabc"
b = b.replace("a","d")
print(b)
# 可以一次把所有a換掉!
# dbcdbc

好像上次有一題...搭配這個可以解決喔 :eyes:

以for迴圈迭代string

a = "Jonathan"
for i in a:
  print(i)
# J
# o
# n
# a
# t
# h
# a
# n
  • 格式:for 迭代的變數 in 字串名
  • 迭代的變數型態為 str,會把字串的每個字元跑過一遍

ASCII code

ASCII code 與 str 互換

  • chr(): ASCII => str
  • ord(): str => ASCII 
print(ord("a"))
print(chr(97))
# 97
# a

b = ord("a")
b += 25
print(chr(b))
# z

print(type(chr(97)))
print(type(ord("a")))
# <class 'str'>
# <class 'int'>

We've come a long way!

現在是例題時間

小小ㄉ例題

在某日下午,建中的高二生段考成績排名出爐了。田鼠很隨興的查了一下自己排名,結果發現自己竟然班排三!這時大家都對他刷著一排含有"dian"的語句。但他因為太想要裝弱了,所以來求你幫他把字串裡所有的"dian"換成"weak"。請聰明的你來幫幫他吧!順便譴責一下這種裝弱的行為。

我顯然也知道可以用.replace()吧w

請試著在不使用這個函式的情況下寫出來吧~

範例輸入

dian explosion

範例輸出

weak explosion

tuple

what is tuple? 

元組!

     tuple基本性質:

  • 可迭代,不可修改
  • 資料儲存較為安全,執行時的速度也較快

宣告元組

宣告空元組:元組名 = ()

宣告非空元組:

  • 元組名 = (變數1, 變數2, ...)
  • 如果只有一個變數,後面要加個逗號!
  • 這邊的宣告可以省略括號
a = ()
print(type(a))
# <class 'tuple'>

b = 1,2,3
print(type(b))
# <class 'tuple'>

c = 1,
print(type(c))
# <class 'tuple'>

d = (1)
print(type(d))
# <class 'int'>

宣告元組

  • 除了元組不能新增、刪除、修改裡面的值之外
  • 指令操作跟 list 一樣
a = (123, 'abc', True)
print(a[1]) #abc
print(a.index(123)) #0
print(a[::-1]) #(True, 'abc', 123)

for i in a:
  print(i, end=' ')
  #123 abc True

tuple (元組)和 list (串列) 互換

  • list()可以將 tuple 轉換成 list
  • tuple()則將 list 轉成 tuple
a = (1, 2, 3)
b = [4, 5, 6]
c = list(a)
d = tuple(b)
print(c, type(c))
print(d, type(d))
# [1, 2, 3] <class 'list'>
# (4, 5, 6) <class 'tuple'>

set

what is set? 

集合!

     set基本性質:

  • 可迭代,可修改
  • 儲存的變數不會重複!(遇到重複的會取代)
  • 沒有順序性
  • 支援邏輯運算

宣告集合

  • 集合名 = set()
  • 集合名 = set([變數1, 變數2, ...]
  • 集合名 = set{變數1, 變數2, ...}
a = set() #空集合
a = {0, 1, 2}
print(a)
print(type(a))
#{0, 1, 2}

b = set([0, 1, 0, 2])
print(b)
#{0, 1, 2}
#無序性
c = {1, 2}
d = {2, 1}
print(c==d) #True

變數 in set

  • 可以判斷某個咚咚有沒有出現在set裡面
a = {123, 'abc', True}
print(123 in a) # True
print("no." in a) # False

set.add()

  • 可以移除()內的值
  • 當然set也有.remove()
  • .discard()遇到不存在的值也不會出事
a = {1, 2, 3}
a.discard(1)
print(a)
# {2, 3}
a.discard(0)
print(a)
# {2, 3}
# 不會出事

set.discard()

  • 可以移除()內的值
  • 當然set也有.remove()
  • .discard()遇到不存在的值也不會出事
a = {1, 2, 3}
a.discard(1)
print(a)
# {2, 3}
a.discard(0)
print(a)
# {2, 3}
# 不會出事

set邏輯運算

邏輯運算 寫法 等價於
and set1.intersection(set2) set1 & set2
or set1.union(set2) set1 | set2
差集 set1.difference(set2) set1 - set2
xor set1.symmetric_difference(set2) set1 ^ set2

如果想多了解一些集合計算可以點這裡

set邏輯運算

a = {1, 2, 3}
b = {3, 4, 5}
print(a&b) #{3}
print(a.union(b)) #{1, 2, 3, 4, 5}
print(a-b) #{1, 2}
print(a.symmetric_difference(b)) #{1, 2, 4, 5}

小小ㄉ例題時間

dict

what is dict? 

字典!

     dict基本性質:

  • 可迭代,可修改
  • Key-Value pairs

宣告字典

  • 字典名 = {}
  • 字典名 = {鍵1(key): 值1(value), 鍵2: 值2, ...}
  • 字典名 = dict(鍵1=值1, 鍵2=值2, ...)
a = {"x":2, "y":3}
print(type(a))
#<class 'dict'>

b = dict(x=3, y=2)
print(b)
# {'x': 3,'y': 2}

賦予字典值

  • 字典名[鍵]
a = dict()
a["許對弈"] = 1
a["將睿哲"] = 2
a["菜淤衝"] = 3
print(a)
if "菲鼠" in a:
  print(a["菲鼠"])
  #因為沒有"地鼠"這個鍵,所以不會執行

刪除字典值

  • del指令可以刪除該鍵
  • .clear()可以將該字典清空
a = dict()
a['a'] = 1
a['b'] = 2
a['c'] = 3
print(a) #{'a': 1, 'b': 2, 'c': 3}

del a['a']
print(a) #{'b': 2, 'c': 3}

a.clear()
print(a) #{}