📖研習進度


串列(list)

x = [True, 1, 1.0, '1', 1 + 0j, "100", ['a', 'b', 'c']]
x
## [True, 1, 1.0, '1', (1+0j), '100', ['a', 'b', 'c']]
type(x)
## <class 'list'>
len(x)  # 取得list元素個數
## 7
y = [2, 3, [4, 5]]
len(y)  # 只計算第1層元素的個數
## 3
list('NCCU')
## ['N', 'C', 'C', 'U']
list(range(-4, 4))
## [-4, -3, -2, -1, 0, 1, 2, 3]
l2 = [1, 2, [3, 4]]
l3 = [5, 6, [7, 8]]
l2 + l3                                        # list的拼接(concatenation)
## [1, 2, [3, 4], 5, 6, [7, 8]]
l2 * 3                                         # list的重複
## [1, 2, [3, 4], 1, 2, [3, 4], 1, 2, [3, 4]]
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
matrix
## [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
matrix[1]
## [4, 5, 6]
matrix[1][1]
## 5

索引(index)

  • Python索引從0開使,並採[n]取值
x = ["first", "second", "third", "fourth"]
x[0]
## 'first'
x[2]
## 'third'
  • 索引值如為負數,則代表從list尾端開始計數
x[-1]  # 取最後一個位置
## 'fourth'
x[-2]  # 取得倒數第二個位置
## 'third'

切片(slicing)

  • 提取多個元素時採切片(slicing)

  • [index1:index2]:代表指定從index1至index2之間(不包括index2)的元素

L = ['NCCU', 'MoneyBanking', 'QF', 'students', 'class']

L[0:2]
## ['NCCU', 'MoneyBanking']
L[1:3]
## ['MoneyBanking', 'QF']
L[1:-1]
## ['MoneyBanking', 'QF', 'students']
L[-2:-1]
## ['students']
  • 可省略index1或index2
L[:2]   # 只️取前2個元素
## ['NCCU', 'MoneyBanking']
L[2:]   # 不取前2個元素
## ['QF', 'students', 'class']
  • 如兩個索引都省略,則會複製整個list

x = L[:]
x
## ['NCCU', 'MoneyBanking', 'QF', 'students', 'class']
x == L
## True
x is L
## False
  • 如第2個索引值在第1個索引值之前,則回傳empty list
L[-1:2]
## []
  • 更改list的元素
x = [1, 2, 3]
x[1:2] = [8, 9]  # 長度可變:insertion
x
## [1, 8, 9, 3]
x = [1, 2, 3]
x[1:1] = [8, 9]  # 長度可變:insertion, replace nothing
x
## [1, 8, 9, 2, 3]
x = [1, 2, 3, 4]
x[len(x):] = [5, 6, 7] 
x
## [1, 2, 3, 4, 5, 6, 7]
x[:0] = [-1, 0]
x
## [-1, 0, 1, 2, 3, 4, 5, 6, 7]
x[1:-1] = []   # 移除list內多個元素
x
## [-1, 7]
# R code:
# L <- list(1, 2, 3)   
# L[1] <- list(8, 9)  
# 被替換的項目不是替換值長度的倍數
L = [1]
L[:0] = [2, 3, 4]            # insert all at 0 
L
## [2, 3, 4, 1]
L[len(L):] = [5, 6, 7]       # insert all at len(L)
L
## [2, 3, 4, 1, 5, 6, 7]
L.extend([8, 9, 10])         # insert all at end, by method
L
## [2, 3, 4, 1, 5, 6, 7, 8, 9, 10]

list更多的操作

append()方法與extend()方法

L = ['eat', 'more', 'SPAM']
L.append('please')
L
## ['eat', 'more', 'SPAM', 'please']
x = [1, 2, 3, 4]
y = [5, 6, 7]
x.append(y)
x
## [1, 2, 3, 4, [5, 6, 7]]
x = [1, 2, 3, 4]
y = [5, 6, 7]
x.extend(y)     # 請與L.extend() method 比較
x 
## [1, 2, 3, 4, 5, 6, 7]

insert()方法:可在兩元素之間或list最前端加入新元素

  • list.insert(n, 新元素)等同於 list[n:n] = [新元素]
x = [1, 2, 3]
x.insert(2, 'Hello')   # 在第2個元素之前插入新元素
x
## [1, 2, 'Hello', 3]
x.insert(0, 'start')   # 在第0個元素之前插入新元素
x
## ['start', 1, 2, 'Hello', 3]
x.insert(-1, 'Hi')
x
## ['start', 1, 2, 'Hello', 'Hi', 3]

list的排序

  • list擁有內建sort方法可供排序,為原地排序(sort in place),會改變原本的list內容

  • 可迭代(iterable)的物件不一定有內建sort方法, 如tuplesetdict的key值。

  • 另有「通用函數(universal function)」: sorted(),不做原地修改,回傳一個排序完成的list

  • 數字與字串無法比較

L.sort()
L
## ['SPAM', 'eat', 'more', 'please']
L.append(['Chen'])           # 請與L.extend() method 比較
L
# L.sort()
# TypeError: '<' not supported between instances of 'list' and 'str'
# 
# Detailed traceback: 
#   File "<string>", line 1, in <module>
## ['SPAM', 'eat', 'more', 'please', ['Chen']]
L = ['abc', 'ABD', 'aBe']
L.sort()
L
## ['ABD', 'aBe', 'abc']
L = ['abc', 'ABD', 'aBe']
L.sort(key = str.lower)
L
## ['abc', 'ABD', 'aBe']
L = ['abc', 'ABD', 'aBe']
L.sort(key = str.lower, reverse = True)
L
## ['aBe', 'ABD', 'abc']
x = [[3, 5], [2, 9], [2, 3], [4, 1], [3,2], [2, 9, 1], [3]]
x.sort()
x
## [[2, 3], [2, 9], [2, 9, 1], [3], [3, 2], [3, 5], [4, 1]]
x.sort(reverse=True)
x
## [[4, 1], [3, 5], [3, 2], [3], [2, 9, 1], [2, 9], [2, 3]]
L = ["abf", "ABe", "aBD"]
L
## ['abf', 'ABe', 'aBD']
L.sort(key=str.lower)
L
## ['aBD', 'ABe', 'abf']
  • 以函數自定義排序
def compare_num_of_chars(string1):
    return len(string1)

def compare_num_of_chars(string1):
  return len(string1)
word_list = ['Python', 'is', 'better', 'than', 'C']
word_list.sort()
print(word_list)
## ['C', 'Python', 'better', 'is', 'than']
word_list = ['Python', 'is', 'better', 'than', 'C']
word_list.sort(key=compare_num_of_chars)
print(word_list)
## ['C', 'is', 'than', 'Python', 'better']
['C', 'is', 'than', 'Python', 'better']
## ['C', 'is', 'than', 'Python', 'better']
x = [4, 3, 1, 2]
sorted(x)
## [1, 2, 3, 4]

刪除元素

  • del可使程式碼可讀性提高
x = [1, 2, 4, 5]
del x[1]
x
## [1, 4, 5]
x = ["a", "c", 1, 2, 3, 4]
del x[:2]
x
## [1, 2, 3, 4]
  • 在list中找到指定值的第1個值,並刪除之:remove()
x = [1, 2, 3, 4, 3, ]
x.remove(3)
x
## [1, 2, 4, 3]
x.remove(3)
x

# x.remove(3)
# x
# ValueError: list.remove(x): x not in list
## [1, 2, 4]

反轉list元素

  • reverse()
x = [1, 2, 3, 4]
x.reverse()
x
## [4, 3, 2, 1]
L = ['spam', 'eggs', 'ham']
L.index('eggs')

# L.index('egg')
# ValueError: 'egg' is not in list
# 
# Detailed traceback: 
#   File "<string>", line 1, in <module>
## 1
L.insert(1, 'toast')
L
## ['spam', 'toast', 'eggs', 'ham']
L.remove('eggs')
L
## ['spam', 'toast', 'ham']
L.pop(1)                              # delete by position
## 'toast'
L
## ['spam', 'ham']
['1', '2', '1', '1', '3'].count('1')  # number of occurences
## 3
L = ['spam', 'eggs', 'ham', 'toast']
del L[0]
L
## ['eggs', 'ham', 'toast']
del L[1:3]
L
## ['eggs']
  • 其他操作
3 in [3, 1, 4, 5]
## True
3 not in [2, 1, 5, 2]
## True
z = [2, 1, 2 ] + [3, 4, 5]
z
## [2, 1, 2, 3, 4, 5]
z = [None] * 5
z
## [None, None, None, None, None]
z = [4, 1, 2] * 2
z
## [4, 1, 2, 4, 1, 2]
min(z)
## 1
max(z)
## 4
L = [1, 2,]
L.extend([3, 4, 5])
L
## [1, 2, 3, 4, 5]
L.pop()     # # Delete and return last item (by default: −1)
## 5
L
## [1, 2, 3, 4]
L.reverse()
L
## [4, 3, 2, 1]
reversed(L)
## <list_reverseiterator object at 0x7f997f62efa0>
list(reversed(L))
## [1, 2, 3, 4]

list iteration與list comprehension(串列生成式)

for x in [1, 2, 3]:
  print(x, end="\n")
  
## 1
## 2
## 3
res = []
for c in "SPAM":
  res.append(c * 4)

res
## ['SSSS', 'PPPP', 'AAAA', 'MMMM']
[c * 4 for c in "SPAM"]
## ['SSSS', 'PPPP', 'AAAA', 'MMMM']

高階函數(Higher-Order function)初探

list(map(abs, [-1, -2, 0, 1, 2]))   # map a function across a seqence
## [1, 2, 0, 1, 2]
list(map(len, [[1, 2, 3], [2, 1], [5, 5, 5, 5]]))
## [3, 2, 4]

深層複製(deep copy)

  • list:可嵌套(nested)
m = [[0, 1, 2], [10, 11, 12], [20, 21, 22]]
m
## [[0, 1, 2], [10, 11, 12], [20, 21, 22]]
m[0]
## [0, 1, 2]
m[0][1]
## 1
m[2][2]
## 22
  • shallow copy VS deep copy
nested = [0]
original = [nested, 1]
original 
## [[0], 1]
nested[0] = 'zero'
original
## [['zero'], 1]
original[0][0] = 0
nested
## [0]
original
## [[0], 1]
nested = [2]   # 將nested改設定為另一個list, 則之間的連結則會被破壞
original
## [[0], 1]

淺層複製不會將第二層以上的list複製一份,而是參考到原list

original = [[0], 1]
shallow = original[:]    # 淺層複製(shallow copy)
import copy
deep = copy.deepcopy(original)


shallow[1] = 2
shallow
## [[0], 2]
original
## [[0], 1]
shallow[0][0] = 'zero'
original
## [['zero'], 1]
deep[0][0] = 5
deep
## [[5], 1]
original
## [['zero'], 1]

元組(tuple)

import random
t0 = ()    # empty tuple
t0
## ()
type(t0)
## <class 'tuple'>
t1 = (1, 2, 2, random.gauss(10, 2))
t1
## (1, 2, 2, 7.724059356332024)
type(t1)
## <class 'tuple'>
t2 = 2, 4, 8, 1
t2
## (2, 4, 8, 1)
type(t2)
## <class 'tuple'>
max(t2)
## 8
t3 = 3,
type(t3)
## <class 'tuple'>
5 in (4, 1, 2, 4, 5, 2)
## True

自動打包(packing)與解包(unpacking)

(one, two, three, four) = (1, 2, 3, 4)  # 自動打包(packing)後自動解包(unpacking),同時指定4個變數值
one
## 1
two
## 2
x, y, z, p = 1, 2, 3, 4    # 會將所有逗號,分隔的資料打包為tuple
z, p
## (3, 4)
  • 自動打包與自動解包不只適用於tuple,只要是序列型別都適用
  • 用於交換變數時相當方便
v1, v2, v3 = [1, 2, 3]
v1
## 1
w1, w2, w3 = 'abc'
w2

# q1, q2 = 'ABC' # 多重指定變數值時,兩邊數量要一樣多
# ValueError: too many values to unpack (expected 2)
# 
# Detailed traceback: 
#   File "<string>", line 1, in <module>
## 'b'
a = 100
b = 200

temp = a
a = b
b = temp
a, b
## (200, 100)
a = 100
b = 200

a, b = b, a
a, b
## (200, 100)
  • *自動解包

    • *的標記的元素會將所有多餘的項目當作list來接收
# a, b, c = 1, 2, 3, 4
# ValueError: too many values to unpack (expected 3)


a, b, *c = (1, 2, 3, 4)   # 
a
## 1
b
## 2
c
## [3, 4]
a, *b, c = (1, 2, 3, 4)
a
## 1
b
## [2, 3]
c
## 4
*a, b, c = (1, 2, 3, 4)
a
## [1, 2]
b
## 3
c
## 4
a,b,c
## ([1, 2], 3, 4)
a, b, c, d, *e = (1, 2, 3, 4)
a
## 1
b
## 2
c
## 3
e
## []
x = [1, 2, 3, 4, 5]
a, b, *_ = x
a
## 1
b
## 2
_   # 常用來代表用不到的資料
## [3, 4, 5]

listtuple的轉換

  • 可使用list()函數將任何序列型資料轉為list。而tuple()函數則轉為tuple。
list((1, 2, 3, 4))
## [1, 2, 3, 4]
tuple([1, 2, 3, 4])
## (1, 2, 3, 4)
list('NCCU')
## ['N', 'C', 'C', 'U']
tuple('Money and Banking')
## ('M', 'o', 'n', 'e', 'y', ' ', 'a', 'n', 'd', ' ', 'B', 'a', 'n', 'k', 'i', 'n', 'g')

集合(set)

x = {1, 2, 1, 3, 3, 1, 2, 4}
x
## {1, 2, 3, 4}
type(x)
## <class 'set'>
x = set([1, 2, 1, 3, 3, 1, 2, 4])
x
## {1, 2, 3, 4}
type(x)
## <class 'set'>
x.add(6)
x
## {1, 2, 3, 4, 6}
x.remove(2)
x
## {1, 3, 4, 6}
3 in x
## True
5 in x
## False
x = {1, 2, 1, 2, 1, 2}
y = set([1, 7, 7, 8, 9])
x
## {1, 2}
y
## {8, 1, 9, 7}
x | y  # 聯集
## {1, 2, 7, 8, 9}
x & y  # 交集
## {1}
x ^ y  # Symmetric Difference (XOR): 只屬於其中一個集合,且不屬於另一個集合之元素所形成的集合
## {2, 7, 8, 9}
x - y  # 差集
## {2}
x1 = {'foo', 'bar', 'baz'}
x1.issubset({'foo', 'bar', 'baz', 'qux', 'quux'})
## True
x1 <= {'foo', 'bar', 'baz', 'qux', 'quux'}
## True
x2 = {'baz', 'qux', 'quux'}
x1 <= x2    
## False
v = {"a", "e", "i", "o", "u"}
v.add("x")
v
## {'e', 'x', 'i', 'u', 'o', 'a'}
v.discard("z")     # 與v.remove()不同,當欲移除之元素不存在時,則不會出現錯誤訊息
v
## {'e', 'x', 'i', 'u', 'o', 'a'}
letters = set("alice")
letters
## {'e', 'i', 'a', 'c', 'l'}
letters.intersection(v)
## {'e', 'i', 'a'}
letters.union(v)
## {'e', 'x', 'i', 'a', 'c', 'o', 'l', 'u'}
letters.difference(v)
## {'l', 'c'}
letters.symmetric_difference(v)
## {'x', 'c', 'u', 'o', 'l'}
s = {"a", "e"}
s.issubset(letters)
## True
letters.issuperset(s)
## True
letters.isdisjoint(s)
## False
x = set([1, 2, 3, 1, 3, 5])
z = frozenset(x)
type(x)
## <class 'set'>
type(z)
## <class 'frozenset'>
# z.add(6)
# AttributeError: 'frozenset' object has no attribute 'add'
# 
# Detailed traceback: 
#   File "<string>", line 1, in <module>
x.add(z)
x
## {1, 2, 3, 5, frozenset({1, 2, 3, 5})}
len(x)
## 5

字典(dict)

建立dict

ages = {'Mary':13, 'John': 14, 'Tony':13}
type(ages)
## <class 'dict'>
ages
## {'Mary': 13, 'John': 14, 'Tony': 13}
'Mary' in ages
## True
x = {}
x
## {}
type(x)
## <class 'dict'>
x[0] = 'NCCU'  # 此0是當作key,並非當作索引用
x[1] = 'Money and Banking'
x
## {0: 'NCCU', 1: 'Money and Banking'}
x[1]
## 'Money and Banking'
len(x)
## 2
y = []
type(y)
# y[0] = 'NCCU'  # 指定一個不存在的索引值0,值得注意的是:R允許這個操作
# IndexError: list assignment index out of range
# 
# Detailed traceback: 
#   File "<string>", line 1, in <module>
## <class 'list'>
# R code:
l <- list()
l[1] <- "NCCU"
l
## [[1]]
## [1] "NCCU"

dict其他操作

english_to_french = {'red': 'rouge', 'blue': 'bleu', 'green': 'vert'}
len(english_to_french)
## 3
list(english_to_french.keys())
## ['red', 'blue', 'green']
list(english_to_french.values())
## ['rouge', 'bleu', 'vert']
list(english_to_french.items())
## [('red', 'rouge'), ('blue', 'bleu'), ('green', 'vert')]
del english_to_french['green']
list(english_to_french.items())
## [('red', 'rouge'), ('blue', 'bleu')]
'red' in english_to_french
## True
'orange' in english_to_french
## False
english_to_french.get('blue', 'No translation')
## 'bleu'
english_to_french.get('chartreuse', 'No translation')
## 'No translation'
english_to_french.setdefault('chartreuse', 'No translation') # 找不到該值時,會新增 鍵:值
## 'No translation'
x = {0: 'zero', 1: 'one'}
y = x.copy()
y
## {0: 'zero', 1: 'one'}
z = {1: 'One', 2: 'Two'}
x = {0: 'zero', 1: 'one'}
x.update(z)
x
## {0: 'zero', 1: 'One', 2: 'Two'}

字串(str)補充

x = 'Goodbye\n!'   # \n:換行跳脫字元(escape character)
x
## 'Goodbye\n!'
len(x)
## 9
print(x)           # print函數自動在字串尾端添加換行跳脫字元 
## Goodbye
## !
print("HIHI")      # print函數自動在字串尾端添加換行跳脫字元 
## HIHI
y = 'Goodbye!'
len(y)
## 8
print(y)
## Goodbye!
z = 'a\n\tb'
z
## 'a\n\tb'
print(z)
## a
##  b
print("abc\n")    # 2次換行
## abc
print("abc\n", end='')    # 1次換行
## abc
x = "Hello" + "World"
x
## 'HelloWorld'
x = "Hello" "World"    # Python會將空白相隔的字串連接在一起
x
## 'HelloWorld'

split()join():切割與連結字串

  • join()函數用於連結字串

  • +也可以用於連結字串,但+用於連結字串時,會建立新字串。故建立大量字串時,會產生很多無用的字串物件,程式碼效率會變差

" ".join(["join", "puts", "spaces", "between", "elements"])
## 'join puts spaces between elements'
"::".join(["Separated", "with", "colons"])
## 'Separated::with::colons'
"".join(["Separated", "by", "nothing"])
## 'Separatedbynothing'
  • split()會將字串分割為字串list,其預設以空白字元(whitespace)切割字串

  • 空白字元包含空格、換行、定位等字元

x = "You\t\t can have tabs\t\n \t and newlines \n\n mixed in"
x.split()
## ['You', 'can', 'have', 'tabs', 'and', 'newlines', 'mixed', 'in']
x = "Mississippi"
x.split("ss")
## ['Mi', 'i', 'ippi']
x = 'a b c d'
x.split(' ', 1)
## ['a', 'b c d']
x.split(' ', 2)
## ['a', 'b', 'c d']
x.split(' ', 100)
## ['a', 'b', 'c', 'd']

轉換字串為數字

float('123.456')

# float('xxyy') 
# ValueError: could not convert string to float: 'xxyy'
## 123.456
int('3333')

# int('123.456')
# ValueError: invalid literal for int() with base 10: '123.456'
## 3333
int('10000', 8)
## 4096
int('101', 2)
## 5
int('ff', 16)

# int('123456', 6)
# ValueError: invalid literal for int() with base 6: '123456'
## 255

strip()lstrip()rstrip()移除開頭或結尾處的多餘空白

x = "  Hello,    World\t\t "
x.strip()
## 'Hello,    World'
x.lstrip()            # 移除左的空白
## 'Hello,    World\t\t '
'Hello,    World\t\t '
## 'Hello,    World\t\t '
x.rstrip()            # 移除左的空白
## '  Hello,    World'
import string
string.whitespace     # 查詢被Python視為空白的字元
## ' \t\n\r\x0b\x0c'
x = "www.python.org"
x.strip("w")                       
## '.python.org'
x.strip("gor")        # 移除所有g, o, r字元              
## 'www.python.'
x.strip(".gorw")      # 移除所有 ., g, o, r, w字元      
## 'python'
demo = " Demo  Example  "  # 移除所有的空白
demo.replace(" ", "") 
## 'DemoExample'

其他字串相關函數

x = "123"
x.isdigit() 
## True
x.isalpha() 
## False
x = "MM"
x.islower() 
## False
x.isupper() 
## True
  • 一些有用的字串常數
import string
string.ascii_letters
## 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
string.ascii_uppercase
## 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
string.ascii_lowercase
## 'abcdefghijklmnopqrstuvwxyz'
string.digits
## '0123456789'

字串的搜尋

  • in operator
x = "The string"
"str" in x
## True
"sTr" in x
## False
"e s" in x
## True
  • find(string, start, end)
x = "Mississippi"
x.find("ss")
## 2
x.find("zz")    # 找不到傳回-1
## -1
x = "Mississippi"
x.find("s")
## 2
x.find("s",2)    # 從索引2開始尋找
## 2
x.find("s",4)    # 從索引4開始尋找
## 5
x.find("s",4,5)  ## 從索引4開始尋找,並在索引5之前結束
## -1
x.find("ss", 3)
## 5
x.find("ss", 0, 3)
## -1
  • rfind():從字串的結尾向開頭進行搜尋,並傳回搜尋文字最後出現的索引位置
x = "Mississippi"
x.rfind("ss")
## 5
  • index()rindex():index()與rindex()分別與find()和rfind()相同,但index()與rindex()找不到文字時,不會回傳-1而是引發ValueError例外錯誤
x = "Mississippi"
# x.index("zz")
# ValueError: substring not found
  • count()
x = "Mississippi"
x.count("ss")
## 2
x.count("s")
## 4
  • startswith()endswith()
x = "Mississippi"
x.startswith("Miss")
## True
x.startswith("Mist")
## False
x.endswith("pi")
## True
x.endswith("p")
## False

字串的修改

  • 雖然字串為不可變資料型態,但字串物件仍提供幾個method可對該字串進行操作,並回傳一個修改後的新字串

  • replace()

x = "Mississippi"
x.replace("ss", "+++")
## 'Mi+++i+++ippi'
  • maketrans()translate()
x = "~x ^ (y % z)"
table = x.maketrans("~^()", "!&[]")   # 組成一個字元參照表
type(table)                           # 按照參照表table來替換字元
## <class 'dict'>
x.translate(table)
## '!x & [y % z]'
  • 透過list來修改字串
text = "Hello, World"
wordList = list(text)
wordList[6:] = []       
wordList.reverse()
text = "".join(wordList)
print(text)      
## ,olleH

透過repr()str()將物件轉換為字串表示

  • repr()傳回的字串是給Python程式讀取(formal string representation),可透過此字串重建原始物件

  • str()傳回的字串是給人看的(informal string representation),可讀性比較高

  • 許多情況之下,repr()str()內容並無不同

repr([1,2,3,4])
## '[1, 2, 3, 4]'
x = [1]
x.append(2)
x
## [1, 2]
x.append([3, 4])
x
## [1, 2, [3, 4]]
"The list x is " + repr(x)
## 'The list x is [1, 2, [3, 4]]'
repr(len)
## '<built-in function len>'
repr(list)
## "<class 'list'>"
from datetime import datetime
now = datetime.now()
str(now)
## '2021-04-07 14:40:55.179231'
print(now)
## 2021-04-07 14:40:55.179231
repr(now)
## 'datetime.datetime(2021, 4, 7, 14, 40, 55, 179231)'

使用%格式化字串

  • 舊式做法

  • 常用的格式化規範

    字串 意義
    %s 字串
    %c 字元
    %b 二進位
    %d 十進位
    %x 十六進位
    %f 浮點數
    %e 指數
    不指名 與d相同
errno = 12345
name = "Bob"

"Hello, %s" % name   # %s 告訴Python此處要替換成字串,他會到第二個 % 運算子後面找到變數
## 'Hello, Bob'
"%x" % errno         # %x 把整數轉換成字串並以16進位數字表示
## '3039'
"Hi, %s, 錯誤:0x%x 發生了" % (name, errno)
## 'Hi, Bob, 錯誤:0x3039 發生了'
"Hi, %(Name)s, 錯誤:0x%(errNo)x 發生了" % {"errNo":errno, "Name":name} 
## 'Hi, Bob, 錯誤:0x3039 發生了'

使用format()格式化字串

  • 使用位置參數
"{} is the {} of {}".format("Ambrosia", "food", "the gods")
## 'Ambrosia is the food of the gods'
"{{Ambrosia}} is the {} of {}".format("food", "the gods")
# 若格式化字串內需顯示{與}字元,則需重複寫兩次{{與}}
## '{Ambrosia} is the food of the gods'
"{} + {} = {}".format(1, 2, 1+2)
## '1 + 2 = 3'
x = [1, 2, "three"]
"The {} contains: {}".format("list", x)
## "The list contains: [1, 2, 'three']"
  • 使用編號參數
"{2} is the {0} of {1}".format("food", "the gods", "Ambrosia")
## 'Ambrosia is the food of the gods'
'{0}{1}{0}'.format('abc', 'def')
## 'abcdefabc'
  • 使用具名參數(named parameter)
"{food} is the food of {user}".format(food="Ambrosia", user="the gods") 
## 'Ambrosia is the food of the gods'
"{0} is the food of {user[1]}".format("Ambrosia", user=["men", "the gods", "others"]) 


# "{0} is the food of {user}".format(user="the gods", "Ambrosia")
# SyntaxError: non-keyword arg after keyword arg
## 'Ambrosia is the food of the gods'
import math
"{}為 {}".format("圓周率", math.pi)
## '圓周率為 3.141592653589793'
"{:10s}為 {:10.5f}".format("圓周率", math.pi)
# 寬度為10, 類型為字串,字串預設靠左
# 寬度為10, 取5位小數點, 類型為浮點數(f), 數字預設靠右
## '圓周率       為    3.14159'
"{:>10s}為 {:+10.5f}".format("圓周率", math.pi)
# 寬度為10, 類型為字串,字串靠右
# 寬度為10, 取5位小數點, 類型為浮點數(f), 數字預設靠右, 並顯示+-號
## '       圓周率為   +3.14159'
"{0:*<10s}為 {1:#> 10.5f}".format("圓周率", math.pi)
# 寬度為10, 靠左(<), 多餘空格用*字元填滿, 並以編號0來取得format()內第0個參數
# 寬度為10, 取5位小數點, 類型為浮點數(f), 空格代表若為正數就留空格,若為負數則加負號, 剩下空格用#字元填滿, 並用編號1來取得format()內第1個參數
## '圓周率*******為 ## 3.14159'
"{0:*<10s}為 {1:#>+10.5f}".format("圓周率", math.pi)
## '圓周率*******為 ##+3.14159'
"{name:P^10s}為 {value:=+10.2f}".format(name = "圓周率", value = math.pi)
# 寬度為10, 置中(^), 多餘空格用P字元填滿, 並以名稱name來取得format()內參數
# 寬度為10, 取2位小數點, 類型為浮點數(f), +號代表強制加上+-號, =號代表把正負號放到最左邊
## 'PPP圓周率PPPP為 +     3.14'

f-string(Python 3.6+)

  • 可直接將Python運算式嵌入字串中

  • 速度較快

name = "Bob"
f'你好, {name}!'
## '你好, Bob!'
a = 5
b = 10
name = "Peter"
No = 100
f'5 加 10 等於 {a + b}, 而非 {2 * (a + b)}.'
## '5 加 10 等於 15, 而非 30.'
f'Hi~ {name:s}, 有錯誤 0x{errno:x} 發生了!'
# :s代表字串
# :x代表十六進位數
## 'Hi~ Peter, 有錯誤 0x3039 發生了!'
f'Hello, {name:s}'
## 'Hello, Peter'
f'Hello, {name=}'   # 變數名稱後面加『=』, 就會把變數名稱與內容一起印出來
## "Hello, name='Peter'"
f'Hello, {No=}'     # 變數名稱後面加『=』, 就會把變數名稱與內容一起印出來
## 'Hello, No=100'