????????欠4年前自己的一份筆記,獻給今后的自己。
分類
-
數值型
????????int、float、complex、bool -
序列對象
????????字符串 str
????????列表 list
????????tuple -
鍵值對
????????集合set
????????字典dict -
數值型
????????int、float、complex、bool都是class,1、5.0、2+3j都是對象即實例
????????int:python3的int就是長整型,且沒有大小限制,受限于內存區域的大小
????????float:有整數部分和小數部分組成。支持十進制和科學計數法表示。只有雙精度型。
????????complex:有實數和虛數部分組成,實數和虛數部分都是浮點數,3+4.2J
????????bool:int的子類,僅有2個實例True、False對應1和0,可以和整數直接運算 -
類型轉換(built-in)
????????int(x) 返回一個整數
????????float(x) 返回一個浮點數
????????complex(x)、complex(x,y) 返回一個復數
????????bool(x) 返回布爾值,前面講過False等價的對象
數字的處理函數
- round(),四舍五入?
- math模塊、floor()地板、天花板ceil()
- int() 、//
- 舉例:
import mathprint(int(-3.6), int(-2.5), int(-1.4))print(int(3.6), int(2.5), int(1.4))print(7 // 2, 7 // -2, -7 // 2, -(7 // 2))print(2 // 3, -2 // 3, -1 // 3)
print(math.floor(2.5), math.floor(-2.5))
print(round(2.5), round(2.5001), round(2.6))
print(math.ceil(2.5), math.ceil(-2.5))
print(round(3.5), round(3.5001), round(3.6), round(3.3))
print(round(-2.5), round(-2.5001), round(-2.6))
print(round(-3.5), round(-3.5001), round(-3.6), round(-3.3))輸出:-3 -2 -1
3 2 1
3 -4 -4 -3
0 -1 -1
2 -3
2 3 3
3 -2
4 4 4 3
-2 -3 -3
-4 -4 -4 -3
- round(),四舍六入五取偶
- floor()向下取整、ceil()向上取整
- int() 取整數部分
- // 整除且向下取整
- min()
- max()
- pow(x,y) 等于 x**y
- math.sqrt()
- 進制函數,返回值是字符串
????????bin()
????????oct()
????????hex() - math.pi π
- math.e 自如常數
類型判斷
- type(obj) ,返回類型,而不是字符串
- isinstance(obj, class_or_tuple),返回布爾值
舉例:
????????type(a)
????????type(‘abc’)
????????type(123)
????????isinstance(6, str)
????????isinstance(6, (str, bool, int))
????????type(1+True)
????????type(1+True+2.0) # 是什么?隱式轉換
列表list
- 一個隊列,一個排列整齊的隊伍
- 列表內的個體稱作元素,由若干元素組成列表
- 元素可以是任意對象(數字、字符串、對象、列表等)
- 列表內元素有順序,可以使用索引
- 線性的數據結構
- 使用 [ ] 表示
- 列表是可變的
- 列表list、鏈表、queue、stack的差異
列表list定義 初始化
- list() -> new empty list
- list(iterable) -> new list initialized from iterable’s items
- 列表不能一開始就定義大小
lst = list()
lst = []
lst = [2, 6, 9, ‘ab’]
lst = list(range(5))
列表索引訪問
- 索引,也叫下標
- 正索引:從左至右,從0開始,為列表中每一個元素編號
- 負索引:從右至左,從-1開始
- 正負索引不可以超界,否則引發異常IndexError
- 為了理解方便,可以認為列表是從左至右排列的,左邊是頭部,右邊是尾部,左邊是下界,右邊是上界
- 列表通過索引訪問
????????list[index] ,index就是索引,使用中括號訪問
列表查詢
- index(value,[start,[stop]])
通過值value,從指定區間查找列表內的元素是否匹配
匹配第一個就立即返回索引
匹配不到,拋出異常ValueError - count(value)
返回列表中匹配value的次數 - 時間復雜度
index和count方法都是O(n)
隨著列表數據規模的增大,而效率下降 - 如何返回列表元素的個數?如何遍歷?如何設計高效?
len()
如何查幫助
列表元素修改
- 索引訪問修改
list[index] = value
索引不要超界
列表增加、插入元素
- append(object) -> None
列表尾部追加元素,返回None
返回None就意味著沒有新的列表產生,就地修改
時間復雜度是O(1) - insert(index, object) -> None
在指定的索引index處插入元素object
返回None就意味著沒有新的列表產生,就地修改
時間復雜度是O(n)
索引能超上下界嗎?
????????超越上界,尾部追加
????????超越下界,頭部追加 - extend(iteratable) -> None
????????將可迭代對象的元素追加進來,返回None
????????就地修改
+ -> list
????????連接操作,將兩個列表連接起來
????????產生新的列表,原列表不變
????????本質上調用的是__add__()方法 - -> list
????????重復操作,將本列表元素重復n次,返回新的列表
????Python中用[]表示空的list,我們也可以直接在其中填充元素進行初始化:
# Lists store sequences
li = []
# You can start with a prefilled list
other_li = [4, 5, 6]print(li)print(other_li)
????使用append和pop可以在list的末尾插入或者刪除元素:
# Lists store sequences
li = []# Add stuff to the end of a list with append
li.append(1) # li is now [1]
print(li)li.append(2) # li is now [1, 2]
print(li)
li.append(4) # li is now [1, 2, 4]
print(li)
li.append(3) # li is now [1, 2, 4, 3]
print(li)
# Remove from the end with pop
li.pop() # => 3 and li is now [1, 2, 4]
# Let's put it back
li.append(3) # li is now [1, 2, 4, 3] again.print(li)
????list可以通過[]加上下標訪問指定位置的元素,如果是負數,則表示倒序訪問。-1表示最后一個元素,-2表示倒數第二個,以此類推。如果訪問的元素超過數組長度,則會出發IndexError的錯誤。
# Lists store sequences
li = [1,2,3,4,5]# Access a list like you would any array
print(li[0]) # => 1
# Look at the last element
print(li[-1]) # => 5
# Looking out of bounds is an IndexError
print(li[10]) # Raises an IndexError輸出 :
1
5
Traceback (most recent call last):File "/Users/quyixiao/pp/python_lesson/jk/zhushi/test1.py", line 10, in <module>print(li[10]) # Raises an IndexError~~^^^^
IndexError: list index out of range
????list支持切片操作,所謂的切片則是從原list當中拷貝出指定的一段。我們用start:end的格式來獲取切片,注意,這是一個左閉右開區間。如果留空表示全部獲取,我們也可以額外再加入一個參數表示步長,比如[1:5:2]表示從1號位置開始,步長為2獲取元素。得到的結果為[1, 3]。如果步長設置成-1則代表反向遍歷。
# You can look at ranges with slice syntax.
# The start index is included, the end index is not
# (It's a closed/open range for you mathy types.)
li = [1, 2, 4, 3]
print(li[1:3]) # Return list from index 1 to 3 => [2, 4]
print(li[2:]) # Return list starting from index 2 => [4, 3]
print(li[:3]) # Return list from beginning until index 3 => [1, 2, 4]
print(li[::2]) # Return list selecting every second entry => [1, 4]
print(li[::-1]) # Return list in reverse order => [3, 4, 2, 1]
# Use any combination of these to make advanced slices
# li[start:end:step]
????如果我們要指定一段區間倒序,則前面的start和end也需要反過來,例如我想要獲取[3: 6]區間的倒序,應該寫成[6:3:-1]。
只寫一個:,表示全部拷貝,如果用is判斷拷貝前后的list會得到False。可以使用del刪除指定位置的元素,或者可以使用remove方法。
# You can look at ranges with slice syntax.
# The start index is included, the end index is not
# (It's a closed/open range for you mathy types.)
li = [1, 2, 4, 3]# Make a one layer deep copy using slices
li2 = li[:] # => li2 = [1, 2, 4, 3] but (li2 is li) will result in false.
print(li2)
# Remove arbitrary elements from a list with "del"
del li[2] # li is now [1, 2, 3]
print(li)
# Remove first occurrence of a value
li.remove(2) # li is now [1, 3]
print(li)
li.remove(2) # Raises a ValueError as 2 is not in the list
print(li)輸出:
[1, 2, 4, 3]
[1, 2, 3]
[1, 3]Traceback (most recent call last):File "/Users/quyixiao/pp/python_lesson/jk/zhushi/test1.py", line 17, in <module>li.remove(2) # Raises a ValueError as 2 is not in the list~~~~~~~~~^^^
ValueError: list.remove(x): x not in list
????insert方法可以指定位置插入元素,index方法可以查詢某個元素第一次出現的下標。
# You can look at ranges with slice syntax.
# The start index is included, the end index is not
# (It's a closed/open range for you mathy types.)
li = [1, 2, 4, 3]# Insert an element at a specific index
li.insert(1, 2) # li is now [1, 2, 3] again
print(li)# Get the index of the first item found matching the argumentprint(li.index(2)) # => 1
li = [1, 2, 4, 3]
print(li.index(5)) # Raises a ValueError as 4 is not in the list輸出 :
[1, 2, 2, 4, 3]
1
Traceback (most recent call last):File "/Users/quyixiao/pp/python_lesson/jk/zhushi/test1.py", line 14, in <module>print(li.index(5)) # Raises a ValueError as 4 is not in the list~~~~~~~~^^^
ValueError: 5 is not in list
????list可以進行加法運算,兩個list相加表示list當中的元素合并。等價于使用extend方法:
# You can look at ranges with slice syntax.
# The start index is included, the end index is not
# (It's a closed/open range for you mathy types.)
li = [1, 2, 4, 3]other_li = [4, 5, 6]# You can add lists
# Note: values for li and for other_li are not modified.print(li + other_li) # => [1, 2, 3, 4, 5, 6]# Concatenate lists with "extend()"
li.extend(other_li) # Now li is [1, 2, 3, 4, 5, 6]
????我們想要判斷元素是否在list中出現,可以使用in關鍵字,通過使用len計算list的長度:
li = [1, 2, 4, 3]other_li = [4, 5, 6]# Check for existence in a list with "in"
print(1 in li) # => True
# Examine the length with "len()"
print(len(li)) # => 6
列表 *重復的坑
- * -> list
重復操作,將本列表元素重復n次,返回新的列表
x = [[1,2,3]]*3
print(x)
x[0][1] = 20
print(x)
y = [1]*5
y[0] = 6
y[1] = 7
print(y)輸出:
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]
[[1, 20, 3], [1, 20, 3], [1, 20, 3]]
[6, 7, 1, 1, 1]
上面代碼運行結果是什么?為什么?
列表刪除元素
- remove(value) -> None
????????從左至右查找第一個匹配value的值,移除該元素,返回None
????????就地修改
????????效率?
8 pop([index]) -> item
????????不指定索引index,就從列表尾部彈出一個元素
????????指定索引index,就從索引處彈出一個元素,索引超界拋出IndexError錯誤
????????效率?指定索引的的時間復雜度?不指定索引呢? - clear() -> None
????????清除列表所有元素,剩下一個空列表
列表其它操作
- reverse() -> None
????????n將列表元素反轉,返回None
????????就地修改 - sort(key=None, reverse=False) -> None
????????對列表元素進行排序,就地修改,默認升序
????????reverse為True,反轉,降序
????????key一個函數,指定key如何排序
????????lst.sort(key=functionname) - in
???????? [3,4] in [1, 2, [3,4]]
???????? for x in [1,2,3,4]
列表復制
lst0 = list(range(4))
lst2 = list(range(4))
print(lst0==lst2)
lst1 = lst0
lst1[2] = 10
print(lst0)
lst0==lst2相等嗎?為什么?lst0里面存的是什么?
請問lst0的索引為2的元素的值是什么?
請問lst1 = lst0這個過程中有沒有復制過程?輸出:
True
[0, 1, 10, 3]
- copy() -> List shadow copy返回一個新的列表
lst0 = list(range(4))
lst5 = lst0.copy()
print(lst5 == lst0)
lst5[2] = 10
print(lst5 == lst0)
lst0和lst5一樣嗎?
對比左右程序的差別lst0 = [1, [2, 3, 4], 5]
lst5 = lst0.copy()
lst5 == lst0
lst5[2] = 10
lst5 == lst0
lst5[2] = 5
lst5[1][1] = 20
lst5 == lst0輸出:
True
False
- shadow copy
????????影子拷貝,也叫淺拷貝,遇到引用類型,只是復制了一個引用而已 - 深拷貝
????????copy模塊提供了deepcopy
import copy
lst0 = [1, [2, 3, 4], 5]
lst5 = copy.deepcopy(lst0)
lst5[1][1] = 20
lst5 == lst0
隨機數
- random模塊
- randint(a, b) 返回[a, b]之間的整數
- choice(seq) 從非空序列的元素中隨機挑選一個元素,比如random.choice(range(10)),從0到9中隨機挑選一個整數。random.choice([1,3,5,7])
- randrange ([start,] stop [,step]) 從指定范圍內,按指定基數遞增的集合中獲取一個隨機數,基數
????????缺省值為1。 random.randrange(1,7,2) - random.shuffle(list) ->None 就地打亂列表元素
- sample(population, k) 從樣本空間或總體(序列或者集合類型)中隨機取出k個不同的元素,返回
一個新的列表
????????random.sample([‘a’, ‘b’, ‘c’, ‘d’], 2)
????????random.sample([‘a’, ‘a’], 2) 會返回什么結果
????關于list的判斷,我們常用的判斷有兩種,一種是剛才介紹的==,還有一種是is。我們有時候也會簡單實用is來判斷,那么這兩者有什么區別呢?我們來看下面的例子:
a = [1, 2, 3, 4] # Point a at a new list, [1, 2, 3, 4]
print(a)
b = a # Point b at what a is pointing to
print(b is a) # => True, a and b refer to the same object
print(b == a) # => True, a's and b's objects are equal
b = [1, 2, 3, 4] # Point b at a new list, [1, 2, 3, 4]
print(b is a) # => False, a and b do not refer to the same object
print(b == a) # => True, a's and b's objects are equal
????Python是全引用的語言,其中的對象都使用引用來表示。is判斷的就是兩個引用是否指向同一個對象,而==則是判斷兩個引用指向的具體內容是否相等。舉個例子,如果我們把引用比喻成地址的話,is就是判斷兩個變量的是否指向同一個地址,比如說都是沿河東路XX號。而==則是判斷這兩個地址的收件人是否都叫張三。
顯然,住在同一個地址的人一定都叫張三,但是住在不同地址的兩個人也可以都叫張三,也可以叫不同的名字。所以如果a is b,那么a == b一定成立,反之則不然。
求100內的素數
import math
import datetimestart = datetime.datetime.now()primenumber = []flag = Falsecount = 1for x in range(3, 100000, 2) :for i in primenumber:if x % i == 0:flag = Truebreakif i >= math.ceil(math.sqrt(x)) :flag = Falsebreakif not flag:#print(x)count += 1primenumber .append (x)delta = (datetime.datetime.now() - start).total_seconds()print(delta)print(count)print ("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
楊輝三角
triangle = [[1], [1, 1]]for i in range(2,6):cur = [1]pre = triangle[i-1]for j in range(len(pre)-1):cur.append(pre[j] + pre[j+1])cur.append (1)triangle.append (cur)print(triangle)
變體一 :
triangle = []n = 6for i in range(n):cur = [1]triangle.append(cur)if i == 0:continuepre = triangle[i - 1]for j in range(len(pre) - 1):cur.append(pre[j] + pre[+1])cur.append(1)print(triangle)
補零(方法2)
除了第一行以外,每一行每一個元素(包括兩頭的1)都是由上一行的元素相加得到。如何得到兩頭的1呢?目標是打印指定的行,所以算出一行就打印一行,不需要用一個大空間存儲所有已經算出的行。
while循環實現
n = 6newline =[1] # 相當于計算好的第一行print(newline)for i in range(1,n):oldline = newline.copy() # 淺拷貝并補0oldline.append(0) # 尾部補0相當于兩端補0newline.clear() # 使用append,所以要清除offset = 0while offset <= i:newline.append(oldline[offset-1] + oldline[offset])offset += 1print(newline)
for循環實現
n = 6newline =[1] # 相當于計算好的第一行print(newline)for i in range(1,n):oldline = newline.copy() # 淺拷貝并補0oldline.append(0) # 尾部補0相當于兩端補0newline.clear() # 使用append,所以要清除for j in range(i+1):newline.append(oldline[j - 1] + oldline[j])print(newline)
????????上面的代碼看似不錯,但行初始化的代碼明顯繁瑣了,進一步簡化
triangle = []n = 6for i in range(n):row = [1] * (i + 1) # 一次性開辟triangle.append(row)for j in range(1, i // 2 + 1): # i=2第三行才能進來# print(i, j)val = triangle[i - 1][j - 1] + triangle[i - 1][j]row[j] = valif i != 2 * j: # 奇數個數的中點跳過row[-j - 1] = valprint(triangle)
????????首先我們明確的知道所求最大行的元素個數,例如前6行的最大行元素個數為6個。下一行等于首元素不變,覆蓋中間元素。
n = 6row = [1] * n # 一次性開辟足夠的空間for i in range(n):offset = n - iz = 1 # 因為會有覆蓋影響計算,所以引入一個臨時變量學院for j in range(1, i // 2 + 1): # 對稱性val = z + row[j]row[j], z = val, row[j]if i != 2 * j:row[-j - offset] = valprint(row[:i + 1])
求楊輝三角第n行第k列的值
計算到m行,打印出k項
# 求m行k個元素# m行元素有m個,所以k不能大于m# 這個需求需要保存m行的數據,那么可以使用一個嵌套機構[L],[],[]]m = 5k = 4triangle = []for i in range(m):# 所有行都需要1開頭row = [1]triangle.append(row)if i == 0:continuefor j in range(1, i):row.append(triangle[i - 1][j - 1] + triangle[i - 1][j])row.append(1)print(triangle)print("---------" * 2)print(triangle[m - 1][k - 1])print("*" * 20)輸出:
[[1], [1, 1], [1, 2, 1], [1, 3, 3, 1], [1, 4, 6, 4, 1]]
------------------
4
********************
算法2
# m行k列的值,C(m-1,k-1)組合數m = 9k = 5# m最大n = m - 1r = k - 1# c(n,r) = c(m-1, k-1) = (m-1) !/((k-1)! (m-r) !)d = n - rtargets = [] # r,n-r, nfactorial = 1# 可以加入k為1或者m的判斷,返回1
for i in range(1, n + 1):factorial *= iif i == r:targets.append(factorial)if i == d:targets.append(factorial)if i == n:targets.append(factorial)# print(targets)print(targets[2] // (targets[0] * targets[1]))輸出:
70
元組tuple
- 一個有序的元素組成的集合
- 使用小括號()表示
- 口元組是不可變對象
????tuple和list非常接近,tuple通過()初始化。和list不同,tuple是不可變對象。也就是說tuple一旦生成不可以改變。如果我們修改tuple,會引發TypeError異常。
# Tuples are like lists but are immutable.
tup = (1, 2, 3)
print(tup[0]) # => 1
tup[0] = 3 # Raises a TypeError輸出 :
1
Traceback (most recent call last):File "/Users/quyixiao/pp/python_lesson/jk/zhushi/test1.py", line 4, in <module>tup[0] = 3 # Raises a TypeError~~~^^^
TypeError: 'tuple' object does not support item assignment
????由于小括號是有改變優先級的含義,所以我們定義單個元素的tuple,末尾必須加上逗號,否則會被當成是單個元素:
# Note that a tuple of length one has to have a comma after the last element but
# tuples of other lengths, even zero, do not.
print(type((1))) # => <class 'int'>
print(type((1,))) # => <class 'tuple'>
print(type(())) # => <class 'tuple'>
????tuple支持list當中絕大部分操作:
# You can do most of the list operations on tuples too
tup = (1, 2, 3)
print(len(tup)) # => 3
print(tup + (4, 5, 6)) # => (1, 2, 3, 4, 5, 6)
print(tup[:2]) # => (1, 2)
print(2 in tup ) # => True輸出 :
3
(1, 2, 3, 4, 5, 6)
(1, 2)
True
????我們可以用多個變量來解壓一個tuple:
# You can unpack tuples (or lists) into variables
a, b, c = (1, 2, 3) # a is now 1, b is now 2 and c is now 3
print(a, b, c)
# You can also do extended unpacking
a, *b, c = (1, 2, 3, 4) # a is now 1, b is now [2, 3] and c is now 4
print(a, b, c)
# Tuples are created by default if you leave out the parentheses
d, e, f = 4, 5, 6 # tuple 4, 5, 6 is unpacked into variables d, eand f
print(d, e, f)
# respectively such that d = 4, e = 5 and f = 6
# Now look how easy it is to swap two values
e, d = d, e # d is now 5 and e is now 4
print(d, e)輸出:
1 2 3
1 [2, 3] 4
4 5 6
5 4
解釋一下這行代碼:
a, *b, c = (1, 2, 3, 4) # a is now 1, b is now [2, 3] and c is now 4
????我們在b的前面加上了星號,表示這是一個list。所以Python會在將其他變量對應上值的情況下,將剩下的元素都賦值給b。補充一點,tuple本身雖然是不可變的,但是tuple當中的可變元素是可以改變的。比如我們有這樣一個tuple:
a = (3, [4])
print(a)a[1].append(0) # 這是合法的
print(a)輸出:
(3, [4])
(3, [4, 0])
????我們雖然不能往a當中添加或者刪除元素,但是a當中含有一個list,我們可以改變這個list類型的元素,這并不會觸發tuple的異常:
轉置矩陣
有一個方陣,左邊方陣,求其轉置矩陣
規律:對角線不動,alillil <=> alili,而且到了對角線,就停止,去做下一行,對角線上的元素不動
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(matrix)count = 0for i, row in enumerate(matrix):for j, col in enumerate(row):if i < j:temp = matrix[i][j]matrix[i][j] = matrix[j][i]matrix[j][i] = tempcount += 1print(matrix)print(count)輸出:[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
3
方法二:
#matrix = [[1,2,3,10],[4,5,6,11],[7,8,9,12],[1,2,3,4]]length = len(matrix)count = 0for i in range(length):for j in range(i): # j<imatrix[i][j],matrix[j][i] = matrix[j][i],matrix[i][j]count += 1print(matrix)print(count)輸出:[[1, 4, 7, 1], [2, 5, 8, 2], [3, 6, 9, 3], [10, 11, 12, 4]]
1
有一個任意矩陣,求其轉置矩陣
算法1
過程就是,掃描matrx第一行,在tm的第一列從上至下附加,然后再第二列附加舉例,掃描第一行1.2,3,加入到tm的第一列,然后掃描第二行4,5,6,追加到tm的第二列
# 定義一個矩陣,不考慮稀疏矩陣# 1 2 3 1 4# 4 5 6 =>> 2 5# 3 6import datetimematrix = [[1, 2, 3], [4, 5, 6]]# matrix = [[1,4],[2,5],[3,6]]tm = []count = 0for row in matrix:for i, col in enumerate(row):if len(tm) < i + 1: # matrix有i列就要為tm創建i行tm.append([])tm[i].append(col)count += 1print(matrix)print(tm)print(count)輸出:[[1, 2, 3], [4, 5, 6]]
[[1, 4], [2, 5], [3, 6]]
6
算法2
思考:
能否一次性開辟目標矩陣的內存空間?
如果一次性開辟好目標矩陣內存空間,那么原矩陣的元素直接移動到轉置矩陣的對稱坐標就行了
# 定義一個矩陣,不考慮稀疏矩陣# 1 2 3 1 4# 4 5 6 =>> 2 5# 3 6import datetimematrix = [[1, 2, 3], [4, 5, 6]]# matrix = [[1,4],[2,5],[3,6]]
tm = [[0 for col in range(len(matrix))] for row in range(len(matrix[0]))]count = 0for i, row in enumerate(tm):for j, col in enumerate(row):tm[i][j] = matrix[j][i] # 將matrix的所有元素搬到tm中count += 1print(matrix)print(tm)print(count)輸出:[[1, 2, 3], [4, 5, 6]]
[[1, 4], [2, 5], [3, 6]]
6
效率測試
import datetimematrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]matrix = [[1, 4], [2, 5], [3, 6]]print('\nMethod 1')start = datetime.datetime.now()
for c in range(100000):tm = [] # 目標矩陣for row in matrix:for i, item in enumerate(row):if len(tm) < i + 1:tm.append([])tm[i].append(item)delta = (datetime.datetime.now() - start).total_seconds()
print(delta)print(matrix)print(tm)print('\nMethod 2')start = datetime.datetime.now()
for c in range(100000):tm = [0] * len(matrix[0])for i in range(len(tm)):tm[i] = [0] * len(matrix)# print(tm)for i, row in enumerate(tm):for j, col in enumerate(row):tm[i][j] = matrix[j][i]delta = (datetime.datetime.now() - start).total_seconds()
print(delta)print(matrix)print(tm)輸出:Method 1
0.094851
[[1, 4], [2, 5], [3, 6]]
[[1, 2, 3], [4, 5, 6]]Method 2
0.100858
[[1, 4], [2, 5], [3, 6]]
[[1, 2, 3], [4, 5, 6]]
說明:
上面兩個方法在ipython中,使用%%timeit測試下來方法一效率高。
但是真的是方法一效率高嗎?
給一個大矩陣,測試一下
matrix = [[1, 2, 3], [4,5, 6], [1, 2, 3], [4,5, 6], [1,2, 3], [4,5, 6], [1, 2,3], [4,5, 6], [1, 2, 3], [4, 5, 6], [1, 2, 3], [4, 5, 6], [1, 2, 3], [4,5, 6], [1, 2, 3], [4,5, 6], [1, 2, 3], [4,5, 6], [1, 2, 3], [4, 5, 6], [1, 2, 3], [4, 5, 6], [1, 2, 3], [4, 5, 6], [1, 2, 3], [4,5, 6], [1, 2, 3], [4,5, 6], [1, 2, 3], [4,5, 6], [1, 2, 3],
[4,5,6]]
測試發現,其實只要增加到4*4開始,方法二優勢就開始了。
矩陣規模越大,先開辟空間比后append效率高。
元組的定義 初始化
- 定義
????????tuple() -> empty tuple
????????tuple(iterable) -> tuple initialized from iterable’s items
t = tuple() # 工廠方法
t = ()
t = tuple(range(1,7,2)) # iteratable
t = (2,4,6,3,4,2)
t = (1,) # 一個元素元組的定義,注意有個逗號
t = (1,)*5
t = (1,2,3) * 6
元組元素的訪問
-
支持索引(下標)
-
正索引:從左至右,從0開始,為列表中每一個元素編號口
-
負索引:從右至左,從-1開始
-
正負索引不可以超界,否則引發異常IndexError
-
元組通過索引訪問
????????tuple[index],index就是索引,使用中括號訪問
t[1]
t[-2]
t[1] = 5
元組查詢
- index(value,[start,[stop]])
通過值value,從指定區間查找列表內的元素是否匹配
匹配第一個就立即返回索引
匹配不到,拋出異常ValueError - count(value)
返回列表中匹配value的次數 - 時間復雜度
index和count方法都是O(n)
隨著列表數據規模的增大,而效率下降 - len(tuple)
返回元素的個數
元組其它操作
- 元組是只讀的,所以增、改、刪方法都沒有
命名元組namedtuple
- 幫助文檔中,查閱namedtuple,有使用例程
- namedtuple(typename, field_names, verbose=False, rename=False)
???????? 命名元組,返回一個元組的子類,并定義了字段
???????? field_names可以是空白符或逗號分割的字段的字符串,可以是字段的列表
from collections import namedtuple
Point = namedtuple('_Point',['x','y']) # Point為返回的類
p = Point(11, 22)
Student = namedtuple('Student', 'name age')
tom = Student('tom', 20)
jerry = Student('jerry', 18)
tom.name
練習
- 依次接收用戶輸入的3個數,排序后打印
- 轉換int后,判斷大小排序。使用分支結構完成
- 使用max函數
- 使用列表的sort方法
- 冒泡法
冒泡法
- 冒泡法
屬于交換排序
兩兩比較大小,交換位置。如同水泡咕嘟咕嘟往上冒
結果分為升序和降序排列 - 升序
????????n個數從左至右,編號從0開始到n-1,索引0和1的值比較,如果索引0大,則交換兩者位置,如果索引1大,則不交換。繼續比較索引1和2的值,將大值放在右側。直至n-2和n-1比較完,第一輪比較完成。第二輪從索引0比較到n-2,因為最右側n-1位置上已經是最大值了。依次類推,每一輪都會減少最右側的不參與比較,直至剩下最后2個數比較。 - 降序
和升序相反
冒泡法代碼實現(一)
from sortTest.Maopao1 import num_listnum_list = [[1, 9, 8, 5, 5, 6, 7, 4, 3, 2],[1, 2, 3, 4, 5, 6, 7, 8, 9]]nums = num_list[1]print(nums)length = len(nums)count_swap = 0count = 0# bubble sortfor i in range(length):for j in range(length - i - 1):count += 1if nums[j] > nums[j + 1]:tmp = nums[j]nums[j] = nums[j + 1]nums[j + 1] = tmpcount_swap += 1print(nums, count_swap, count)
冒泡法代碼實現(二)
num_list = [[1, 9, 8, 5, 6, 7, 4, 3, 2],[1, 2, 3, 4, 5, 6, 7, 8, 9],[1, 2, 3, 4, 5, 6, 7, 8, 9]]nums = num_list[2]
print(nums)
length = len(nums)
count_Swap = 0
count = 0# bubble sortfor i in range(length):flag = Falsefor j in range(length - i - 1):count += 1if nums[j] > nums[j + 1]:tmp = nums[j]nums[j] = nums[j + 1]nums[j + 1] = tmpflag = True # swappedcount_Swap += 1if not flag:breakprint(nums, count_Swap, count)
例一:
from collections import namedtuplePoint = namedtuple('P', ['x', 'y'])
print(Point)p1 = Point(10, 20)
print(p1)print(p1.x, p1.y)print(p1[0], p1[1])Student = namedtuple('stu','name age')
s1 = Student('tom',20)
s2 = Student('jerry',30)
print(s1.name)
print(s2.age)結果輸出:
<class '__main__.P'>
P(x=10, y=20)
10 20
10 20
tom
30
例二:
def sum(a,b):return a ,ba,b = sum(1,2)
print(a,b)輸出:
1 2
例三:
a = tuple([1,2])
print(a )輸出:(1, 2)
冒泡法總結
- 冒泡法需要數據一輪輪比較
- 可以設定一個標記判斷此輪是否有數據交換發生,如果沒有發生交換,可以結束排序,如果發生交換,繼續下一輪排序
- 最差的排序情況是,初始順序與目標順序完全相反,遍歷次數1,…,n-1之和n(n-1)/2
- 最好的排序情況是,初始順序與目標順序完全相同,遍歷次數n-1
- 時間復雜度O(n^2)
字符串
????Python當中對字符串的限制比較松,雙引號和單引號都可以表示字符串,看個人喜好使用單引號或者是雙引號。我個人比較喜歡單引號,因為寫起來方便。字符串也支持+操作,表示兩個字符串相連。除此之外,我們把兩個字符串寫在一起,即使沒有+,Python也會為我們拼接:
# Strings are created with " or '
print("This is a string.")
print('This is also a string.')
# Strings can be added too! But try not to do this.
print( "Hello " + "world!") # => "Hello world!"
# String literals (but not variables) can be concatenated without using '+'
print("Hello " "world!" )# => "Hello world!"
????我們可以使用[]來查找字符串當中某個位置的字符,用len來計算字符串的長度。
# A string can be treated like a list of characters
print("This is a string"[0]) # => 'T'
# You can find the length of a string
print(len("This is a string")) # => 16
????我們可以在字符串前面加上f表示格式操作,并且在格式操作當中也支持運算,比如可以嵌套上len函數等。不過要注意,只有Python3.6以上的版本支持f操作。
# You can also format using f-strings or formatted string literals (in Python 3.6+)
name = "Reiko"
print(f"She said her name is {name}.") # => "She said her name is Reiko"
# You can basically put any Python statement inside the braces and it will be output in the string.
print(f"{name} is {len(name)} characters long.") # => "Reiko is 5 characters long."
????最后是None的判斷,在Python當中None也是一個對象,所有為None的變量都會指向這個對象。根據我們前面所說的,既然所有的None都指向同一個地址,我們需要判斷一個變量是否是None的時候,可以使用is來進行判斷,當然用==也是可以的,不過我們通常使用is。
# None is an object
print(None) # => None
# Don't use the equality "==" symbol to compare objects to None
# Use "is" instead. This checks for equality of object identity.
print("etc" is None) # => False
print(None is None) # => True
????理解了None之后,我們再回到之前介紹過的bool()函數,它的用途其實就是判斷值是否是空。所有類型的默認空值會被返回False,否則都是True。比如0,“”,[], {}, ()等。
# None, 0, and empty strings/lists/dicts/tuples all evaluate toFalse.
# All other values are True
print(bool(None)) # => False
print(bool(0)) # => False
print(bool("")) # => False
print(bool([])) # => False
print(bool({})) # => False
print(bool(())) # => False
????除了上面這些值以外的所有值傳入都會得到True。
幾種字符串的表示
????在Python中,字符串是一種基本的數據類型,可以使用多種方式進行表示:
????普通字符串:使用單引號(’或雙引號(”)括起米的字符串,例如:
print('323232')輸出:323232
????原始字符串:使用反斜杠(\)轉義特殊字符的字符串,例如:
????在Python中,r表示原始字符串(raw string)。原始宇符串是一種特類型的字符串,在字符串中不會將反斜杠(\)視為轉義字符,而是作為普通字符原樣輸出。
print(r'hello\nworld!')
輸出:hello\nworld!
????三引號字符串:使用三個引號(單引號或雙引號)括起來的字符串,可以包含多行文本,例如:
????三引號字符串可以用來表示包含多行文本的字符串
????當字符串中包含引號時,為了避免將引號視為轉義字符,
????可以使用三引號字符串。
????三引號字符串也可以用來表示文檔字符串
????f-string: 使用f-string表示格式化的字符串,主要作用是簡化了字符串格式化的過程,使得代碼更加簡潔和易讀。
????f-string使用大寫的F‘或者作為字符串的前綴,然后在字符串中用花括號日來標記需要插入或替換的表達式。
for i in range(5):print(f'第{i + 1} 個數字是{i}')
Unicode字符串和字節串
????Unicode字符串通常用于表示包含非ASCII拿符的字符串,比如包含中文字符或特殊符號的文本。
????在Python中,Unicode字符串通常以u或U“作為前綴, Unicode字符串表示的是字符本身,而不是它們的編碼形式。
# codecs是Python的一個標準庫,它提供了對各種字符編碼的讀取和寫入操作的支持。import codecs# 定義一個包含中文字符的Unicode字符串text = u'hello, Python! '# 打印該字符串print(text)# 將該字符串寫入文件with codecs.open('output.txt', 'w', 'utf-8') as f:f.write(text)
????字節串 (Byte String)是一種特的數據類型,用于表示二進制數據。字節串以b或bytes作前綴, 并且包含了一串字符的ASCI碼表示。每個字符都是一個字節,因此字節串可以包含多個字節。
# 創建一個字符串byte_string = b'Hello,World!'# 打印字符串print(byte_string)# 將字節串轉換成字符串(需要解碼 ) strint = byte_string.decode('utf-8')print(strint)# 將字符串轉換成字節串 (需要編碼 )byte_string = strint.encode('utf-8')print(byte_string)
輸出 :
- 一個個字符組成的有序的序列,是字符的集合
使用單引號、雙引號、三引號引住的字符序列
字符串是不可變對象
Python3起,字符串就是Unicode類型
字符串定義 初始化
s1 = 'string'
s2 = "string2"
s3 = '''this's a "String" '''
s4 = 'hello \n magedu.com'
s5 = r"hello \n magedu.com"
s6 = 'c:\windows\nt'
s7 = R"c:\windows\nt"
s8 = 'c:\windows\\nt'
sql = """select * from user where name='tom' """
字符串元素訪問——下標
- 字符串支持使用索引訪問
sql = "select * from user where name='tom'"
print(sql)
print(sql[4]) # 字符串'c'
sql[4] = 'o'
## print(sql)輸出:select * from user where name='tom'
cTraceback (most recent call last):File "/Users/quyixiao/pp/python_lesson/jk/zhushi/test2.py", line 4, in <module>sql[4] = 'o'~~~^^^
TypeError: 'str' object does not support item assignment
- 有序的字符集合,字符序列
sql = "select * from user where name='tom'"
for c in sql:print(c)print(type(c)) # 什么類型?輸出:
s
<class 'str'>
e
<class 'str'>
l
<class 'str'>
e
<class 'str'>
c
<class 'str'>
t
<class 'str'><class 'str'>
*
<class 'str'><class 'str'>
f
<class 'str'>
r
<class 'str'>
o
<class 'str'>
m
<class 'str'><class 'str'>
u
<class 'str'>
s
<class 'str'>
e
<class 'str'>
r
<class 'str'><class 'str'>
w
<class 'str'>
h
<class 'str'>
e
<class 'str'>
r
<class 'str'>
e
<class 'str'><class 'str'>
n
<class 'str'>
a
<class 'str'>
m
<class 'str'>
e
<class 'str'>
=
<class 'str'>
'
<class 'str'>
t
<class 'str'>
o
<class 'str'>
m
<class 'str'>
'
<class 'str'>
- 可迭代
sql = "select * from user where name='tom'"
lst = list(sql)
print(lst)輸出:
['s', 'e', 'l', 'e', 'c', 't', ' ', '*', ' ', 'f', 'r', 'o', 'm', ' ', 'u', 's', 'e', 'r', ' ', 'w', 'h', 'e', 'r', 'e', ' ', 'n', 'a', 'm', 'e', '=', "'", 't', 'o', 'm', "'"]
字符串join連接*
- “string”.join(iterable) -> str
將可迭代對象連接起來,使用string作為分隔符
可迭代對象本身元素都是字符串
返回一個新字符串
lst = ['1','2','3']
print("\"".join(lst)) # 分隔符是雙引號
print(" ".join(lst))
print("\n".join(lst))
lst = ['1',['a','b'],'3']
print(" ".join(lst))輸出:
1"2"3
1 2 3
1
2
3
Traceback (most recent call last):File "/Users/quyixiao/pp/python_lesson/jk/zhushi/test2.py", line 6, in <module>print(" ".join(lst))~~~~~~~~^^^^^
TypeError: sequence item 1: expected str instance, list found
字符串+連接
- + -> str
將2個字符串連接在一起
返回一個新字符串
a = "1" + "2";print(a)輸出:
12
字符串分割
-
分割字符串的方法分為2類
????????split系
????????????????partition系
????????將字符串按照分隔符分割成若干字符串,并返回列表
????????????????將字符串按照分隔符分割成2段,返回這2段和分隔符的元組 -
split(sep=None, maxsplit=-1) -> list of strings
從左至右
sep 指定分割字符串,缺省的情況下空白字符串作為分隔符
maxsplit 指定分割的次數,-1 表示遍歷整個字符串
s1 = "I'm \ta super student."
print(s1.split())
print(s1.split('s'))
print(s1.split('super'))
print(s1.split('super '))
print(s1.split(' '))
print(s1.split(' ',maxsplit=2))
print(s1.split('\t',maxsplit=2))輸出:
["I'm", 'a', 'super', 'student.']
["I'm \ta ", 'uper ', 'tudent.']
["I'm \ta ", ' student.']
["I'm \ta ", 'student.']
["I'm", '\ta', 'super', 'student.']
["I'm", '\ta', 'super student.']
["I'm ", 'a super student.']
- rsplit(sep=None, maxsplit=-1) -> list of strings
從右向左
sep 指定分割字符串,缺省的情況下空白字符串作為分隔符
maxsplit 指定分割的次數,-1 表示遍歷整個字符串
s1 = "I'm \ta super student."
print(s1.rsplit())
print(s1.rsplit('s'))
print(s1.rsplit('super'))
print(s1.rsplit('super '))
print(s1.rsplit(' '))
print(s1.rsplit(' ',maxsplit=2))
print(s1.rsplit('\t',maxsplit=2))輸出:
["I'm", 'a', 'super', 'student.']
["I'm \ta ", 'uper ', 'tudent.']
["I'm \ta ", ' student.']
["I'm \ta ", 'student.']
["I'm", '\ta', 'super', 'student.']
["I'm \ta", 'super', 'student.']
["I'm ", 'a super student.']
- splitlines([keepends]) -> list of strings
按照行來切分字符串
keepends 指的是是否保留行分隔符
行分隔符包括\n、\r\n、\r等
'ab c\n\nde fg\rkl\r\n'.splitlines()
'ab c\n\nde fg\rkl\r\n'.splitlines(True)
s1 = '''I'm a super student.
You're a super teacher.'''
print(s1)
print(s1.splitlines())
print(s1.splitlines(True))輸出:
I'm a super student.
You're a super teacher.
["I'm a super student.", "You're a super teacher."]
["I'm a super student.\n", "You're a super teacher."]
- partition(sep) -> (head, sep, tail)
從左至右,遇到分隔符就把字符串分割成兩部分,返回頭、分隔符、尾三部分的三元組;如果沒有找到分隔符,就返回頭、2個空元素的三元組
sep 分割字符串,必須指定
s1 = "I'm a super student."
print(s1.partition('s'))
print("==============")
print(s1.partition('stu'))
print("*********************")
print(s1.partition(''))
print("------------------------")
print(s1.partition('abc'))輸出:("I'm a ", 's', 'uper student.')
==============
("I'm a super ", 'stu', 'dent.')
*********************
Traceback (most recent call last):File "/Users/quyixiao/pp/python_lesson/jk/zhushi/test2.py", line 6, in <module>print(s1.partition(''))~~~~~~~~~~~~^^^^
ValueError: empty separator
- rpartition(sep) -> (head, sep, tail)
從右至左,遇到分隔符就把字符串分割成兩部分,返回頭、分隔符、尾三部分的三元組;如果沒有找到分隔符,就返回2個空元素和尾的三元組
字符串大小寫
- upper()
全大寫 - lower()
- 全小寫
- 大小寫,做判斷的時候用
- swapcase()
交互大小寫
字符串排版
- title() -> str
標題的每個單詞都大寫 - capitalize() -> str
???????? 首個單詞大寫 - center(width[, fillchar]) -> str
???????? width 打印寬度
???????? fillchar 填充的字符 - zfill(width) -> str
???????? width 打印寬度,居右,左邊用0填充 - ljust(width[, fillchar]) -> str 左對齊
- rjust(width[, fillchar]) -> str 右對齊
- 中文用的少,了解一下
字符串修改
- replace(old, new[, count]) -> str
字符串中找到匹配替換為新子串,返回新字符串
count表示替換幾次,不指定就是全部替換
print('www.magedu.com'.replace('w','p'))
print('www.magedu.com'.replace('w','p',2))
print('www.magedu.com'.replace('w','p',3))
print('www.magedu.com'.replace('ww','p',2))
print('www.magedu.com'.replace('www','python',2))輸出:
ppp.magedu.com
ppw.magedu.com
ppp.magedu.com
pw.magedu.com
python.magedu.com
字符串修改
- strip([chars]) -> str
從字符串兩端去除指定的字符集chars中的所有字符
如果chars沒有指定,去除兩端的空白字符
s = "\r \n \t Hello Python \n \t"
print(s.strip())
s = " I am very very very sorry "
print(s.strip('Iy'))
print(s.strip('Iy '))輸出:
Hello PythonI am very very very sorry
am very very very sorr
- lstrip([chars]) -> str
從左開始 - rstrip([chars]) -> str
從右開始
字符串查找
- find(sub[, start[, end]]) -> int
????????在指定的區間[start, end),從左至右,查找子串sub。找到返回索引,沒找到返回-1 - rfind(sub[, start[, end]]) -> int
????????在指定的區間[start, end),從右至左,查找子串sub。找到返回索引,沒找到返回-1
s = "I am very very very sorry"
print(s.find('very'))
print(s.find('very', 5))
print(s.find('very', 6, 13))
print(s.rfind('very', 10))
print(s.rfind('very', 10, 15))
print(s.rfind('very',-10,-1))輸出:5
5
-1
15
10
15
- index(sub[, start[, end]]) -> int
????????在指定的區間[start, end),從左至右,查找子串sub。找到返回索引,沒找到拋出異常ValueError - rindex(sub[, start[, end]]) -> int
????????在指定的區間[start, end),從左至右,查找子串sub。找到返回索引,沒找到拋出異常ValueError
s = "I am very very very sorry"
print(s.index('very'))
print("="*60)
print(s.index('very', 5))
print("*"*60)
print(s.index('very', 6, 13))
print("-"*60)
print(s.rindex('very', 10))
print("|"*60)
print(s.rindex('very', 10, 15))
print("/")
print(s.rindex('very',-10,-1))輸出:
5
============================================================
5
************************************************************
Traceback (most recent call last):File "/Users/quyixiao/pp/python_lesson/jk/zhushi/test2.py", line 6, in <module>print(s.index('very', 6, 13))~~~~~~~^^^^^^^^^^^^^^^
ValueError: substring not found
-
時間復雜度
index和count方法都是O(n)
隨著列表數據規模的增大,而效率下降 -
len(string)
返回字符串的長度,即字符的個數 -
count(sub[, start[, end]]) -> int
在指定的區間[start, end),從左至右,統計子串sub出現的次數
s = "I am very very very sorry"
print(s.count('very'))
print(s.count('very', 5))
print(s.count('very', 10, 14))輸出:
3
3
1
字符串判斷
- endswith(suffix[, start[, end]]) -> bool
????????在指定的區間[start, end),字符串是否是suffix結尾 - startswith(prefix[, start[, end]]) -> bool
????????在指定的區間[start, end),字符串是否是prefix開頭
s = "I am very very very sorry"
print(s.startswith('very'))
print(s.startswith('very', 5))
print(s.startswith('very', 5, 9))
print(s.endswith('very', 5, 9))
print(s.endswith('sorry', 5))
print(s.endswith('sorry', 5, -1))
print(s.endswith('sorry', 5, 100))輸出:
False
True
True
True
True
False
True
字符串判斷 is系列
- isalnum() -> bool 是否是字母和數字組成
- isalpha() 是否是字母
- isdecimal() 是否只包含十進制數字
- isdigit() 是否全部數字(0~9)
- isidentifier() 是不是字母和下劃線開頭,其他都是字母、數字、下劃線
- islower() 是否都是小寫
- isupper() 是否全部大寫
- isspace() 是否只包含空白字符
字符串格式化
-
字符串的格式化是一種拼接字符串輸出樣式的手段,更靈活方便
????????join拼接只能使用分隔符,且要求被拼接的是可迭代對象
????????+ 拼接字符串還算方便,但是非字符串需要先轉換為字符串才能拼接 -
在2.5版本之前,只能使用printf style風格的print輸出
????????printf-style formatting,來自于C語言的printf函數
????????格式要求
????????占位符:使用%和格式字符組成,例如%s、%d等
????????s調用str(),r會調用repr()。所有對象都可以被這兩個轉換。
????????占位符中還可以插入修飾字符,例如%03d表示打印3個位置,不夠前面補零
????????format % values,格式字符串和被格式的值之間使用%分隔
????????values只能是一個對象,或是一個和格式字符串占位符數目相等的元組,或一個字典 -
printf-style formatting 舉例
print("I am %03d" % (20,))
print('I like %s.' % 'Python')
print('%3.2f%% , 0x%x, 0X%02X' % (89.7654, 10, 15))
print("I am %-5d" % (20,))輸出:I am 020
I like Python.
89.77% , 0xa, 0X0F
I am 20
-
format函數格式字符串語法——Python鼓勵使用
“{} {xxx}”.format(*args, **kwargs) -> str
args是位置參數,是一個元組
kwargs是關鍵字參數,是一個字典
花括號表示占位符
{}表示按照順序匹配位置參數,{n}表示取位置參數索引為n的值
{xxx}表示在關鍵字參數中搜索名稱一致的
{{}} 表示打印花括號 -
位置參數
“{}:{}”.format(‘192.168.1.100’,8888),這就是按照位置順序用位置參數替換前面的格式字符串的占位符中 -
關鍵字參數或命名參數
“{server} {1}:{0}”.format(8888, ‘192.168.1.100’, server='Web Server Info : ') ,位置參數按照序號匹配,
關鍵字參數按照名詞匹配 -
訪問元素
“{0[0]}.{0[1]}”.format((‘magedu’,‘com’)) -
對象屬性訪問
from collections import namedtuple
Point = namedtuple('Point','x y')
p = Point(4,5)
print("{{{0.x},{0.y}}}".format(p))輸出:
{4,5}
- 對齊
print('{0}*{1}={2:<2}'.format(3,2,2*3))
print('{0}*{1}={2:<02}'.format(3,2,2*3))
print('{0}*{1}={2:>02}'.format(3,2,2*3))
print('{:^30}'.format('centered'))
print('{:*^30}'.format('centered'))輸出:3*2=6
3*2=60
3*2=06centered
***********centered***********
- 進制
print("int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}".format(42))
print("int: {0:d}; hex: {0:#x}; oct: {0:#o}; bin: {0:#b}".format(42))
octets = [192, 168, 0, 1]
print('{:02X}{:02X}{:02X}{:02X}'.format(*octets))
輸出:
int: 42; hex: 2a; oct: 52; bin: 101010
int: 42; hex: 0x2a; oct: 0o52; bin: 0b101010
C0A80001
bytes、bytearray
-
Python3引入兩個新類型
???????? bytes
???????????????? 不可變字節序列
???????? bytearray
???????????????? 字節數組
???????????????? 可變 -
字符串與bytes
字符串是字符組成的有序序列,字符可以使用編碼來理解
bytes是字節組成的有序的不可變序列
bytearray是字節組成的有序的可變序列 -
編碼與解碼
字符串按照不同的字符集編碼encode返回字節序列bytes
???????? encode(encoding=‘utf-8’, errors=‘strict’) -> bytes
字節序列按照不同的字符集解碼decode返回字符串
???????? bytes.decode(encoding=“utf-8”, errors=“strict”) -> str
???????? bytearray.decode(encoding=“utf-8”, errors=“strict”) -> str
ASCII
????????ASCIl ( American Standard Code for Information Interchange,美國信息交換標準代碼)是基于拉丁字母的一套單字節編碼系統
bytes定義
- 定義
bytes() 空bytes
bytes(int) 指定字節的bytes,被0填充
bytes(iterable_of_ints) -> bytes [0,255]的int組成的可迭代對象
bytes(string, encoding[, errors]) -> bytes 等價于string.encode()
bytes(bytes_or_buffer) -> immutable copy of bytes_or_buffer 從一個字節序列或者buffer復制出
????????一個新的不可變的bytes對象
使用b前綴定義
????????只允許基本ASCII使用字符形式b’abc9’
????????使用16進制表示b"\x41\x61"
bytes操作
- 和str類型類似,都是不可變類型,所以方法很多都一樣。只不過bytes的方法,輸入是bytes,輸出是
bytes
b’abcdef’.replace(b’f’,b’k’)
b’abc’.find(b’b’) - 類方法 bytes.fromhex(string)
string必須是2個字符的16進制的形式,‘6162 6a 6b’,空格將被忽略
bytes.fromhex(‘6162 09 6a 6b00’) - hex()
返回16進制表示的字符串
‘abc’.encode().hex() - 索引
b’abcdef’[2] 返回該字節對應的數,int類型
bytearray定義
- 定義
bytearray() 空bytearray
bytearray(int) 指定字節的bytearray,被0填充
bytearray(iterable_of_ints) -> bytearray [0,255]的int組成的可迭代對象
bytearray(string, encoding[, errors]) -> bytearray 近似string.encode(),不過返回可變對象
bytearray(bytes_or_buffer) 從一個字節序列或者buffer復制出一個新的可變的bytearray對象
注意,b前綴定義的類型是bytes類型
bytearray操作
-
和bytes類型的方法相同
bytearray(b’abcdef’).replace(b’f’,b’k’)
bytearray(b’abc’).find(b’b’) -
類方法 bytearray.fromhex(string)
string必須是2個字符的16進制的形式,‘6162 6a 6b’,空格將被忽略
bytearray.fromhex(‘6162 09 6a 6b00’) -
hex()
返回16進制表示的字符串
bytearray(‘abc’.encode()).hex() -
索引
bytearray(b’abcdef’)[2] 返回該字節對應的數,int類型 -
append(int) 尾部追加一個元素
-
insert(index, int) 在指定索引位置插入元素
-
extend(iterable_of_ints)將一個可迭代的整數集合追加到當前bytearray
-
pop(index=-1) 從指定索引上移除元素,默認從尾部移除口 remove(value) 找到第一個value移除,找不到拋 ValueError異常
-
注意:上述方法若需要使用int類型,值在[0,255]
-
clear() 清空bytearray
-
reverse()翻轉bytearray,就地修改
b = bytearray()
b.append (97)
print('append_97:',b)b.append(99)
print('append_99:',b)b.insert (1,98)
print('insert:',b)b.extend ([65,66,67])
print('extend:',b)
b.remove(66)
print('remove_66:',b)print(b.pop())b.reverse()
print('reverse:',b)b.clear()
print(b)輸出:append_97: bytearray(b'a')
append_99: bytearray(b'ac')
insert: bytearray(b'abc')
extend: bytearray(b'abcABC')
remove_66: bytearray(b'abcAC')
67
reverse: bytearray(b'Acba')
bytearray(b'')
切片
線性結構
- 線性結構
可迭代 for … in
len()可以獲取長度
通過下標可以訪問
可以切片 - 學過的線性結構
列表、元組、字符串、bytes、bytearray
切片
- 通過索引區間訪問線性結構的一段數據
- sequence[start:stop] 表示返回[start, stop)區間的子序列
- 支持負索引
- start為0,可以省略
- stop為末尾,可以省略
- 超過上界(右邊界),就取到末尾;超過下界(左邊界),取到開頭
- start一定要在stop的左邊
- [:] 表示從頭至尾,全部元素被取出,等效于copy()方法
切片舉例
print('www.magedu.com'[4:10]) # magedu
print('www.magedu.com'[:10]) # www.magedu
print('www.magedu.com'[4:]) # magedu.com
print('www.magedu.com'[:]) # www.magedu.com
print('www.magedu.com'[:-1]) # www.magedu.co
print('www.magedu.com'[4:-4]) # magedu
print('www.magedu.com'[4:50]) # magedu.com
print(b'www.magedu.com'[-40:10]) # b'www.magedu'
print(bytearray(b'www.magedu.com')[-4:10]) # bytearray(b'')
print(tuple('www.magedu.com')[-10:10]) # ('m', 'a', 'g', 'e', 'd', 'u')
print(list('www.magedu.com')[-10:-4]) # ['m', 'a', 'g', 'e', 'd', 'u']
- 步長切片
[start:stop:step]
step為步長,可以正、負整數,默認是1
step要和start:stop同向,否則返回空序列
print('www.magedu.com'[4:10:2]) # mgd
print(list('www.magedu.com')[4:10:-2]) # []
print(tuple('www.magedu.com')[-10:-4:2]) # ('m', 'g', 'd')
print(b'www.magedu.com'[-4:-10:2]) # b''
print(bytearray(b'www.magedu.com')[-4:-10:-2]) # bytearray(b'.dg')
數字統計
隨機產生10個數字要求:
每個數字取值范圍[1,20]
統計重復的數字有幾個?分別是什么?
統計不重復的數字有幾個?分別是什么?
舉例:11,7.5,11,6, 7.4,其中2個數字7和11重復了,3個數字4、5、6沒有重復過
思路:
對于一個排序的序列,相等的數字會挨在一起。但是如果先排序,還是要花時間,能否不排序解決?
例如11,7,5,11,6,7,4,先拿出11,依次從第二個數字開始比較,發現11就把對應索引標記,這樣
一趟比較就知道11是否重復,哪些地方重復。第二趟使用7和其后數字依次比較,發現7就標記, 當遇到以前比較過的11的位置的時候,其索引已經被標記為1,直接跳過。
import randomnums = []for _ in range(10):nums.append(random.randrange(21))# nums = [1,22,33, 56, 56,22,4,56, 9,56,2,1]print("Origin numbers = {}".format(nums))
print()length = len(nums)samenums = [] # 記錄相同的數字diffnums = [] # 記錄不同的數字states = [0] * length # 記錄不同的索引異同狀態for i in range(length):flag = False # 假定沒有重復if states[i] == 1:continuefor j in range(i + 1, length):if states[j] == 1:continueif nums[i] == nums[j]:flag = Truestates[j] = 1if flag: # 有重復samenums.append(nums[i])states[i] = 1else:diffnums.append(nums[i])print("Same numbers = {1}, Counter = {0}".format(len(samenums), samenums))
print("Different numbers = {1}, Counter = {0}".format(len(diffnums), diffnums))
print(list(zip(states, nums)))