深度之眼 - Python學習筆記——第十章 Python標準庫

第十章 Python標準庫

Python自身提供了比較豐富的生態,拿來即用,可極大的提高開發效率

10.1 time庫

Python處理時間的標準庫

1、獲取現在時間

(1)time.localtime() 本地時間——現在在哪裏就獲得哪裏的時間

(2)time.gmtime() UTC世界統一時間

北京時間比時間統一時間UTC早8個小時

import time

t_local = time.localtime()
t_UTC = time.gmtime()
print("t_local", t_local)           # 本地時間
print("t_UTC", t_UTC)               # UTC統一時間
t_local time.struct_time(tm_year=2020, tm_mon=2, tm_mday=3, tm_hour=22, tm_min=54, tm_sec=38, tm_wday=0, tm_yday=34, tm_isdst=0)
t_UTC time.struct_time(tm_year=2020, tm_mon=2, tm_mday=3, tm_hour=14, tm_min=54, tm_sec=38, tm_wday=0, tm_yday=34, tm_isdst=0)
time.ctime()                      # 返回本地時間的字符串
'Mon Feb  3 22:55:02 2020'

2、時間戳與計時器

(1)time.time()   返回自紀元以來的秒數,記錄sleep

(2)time.perf_counter()   隨意選取一個時間點,記錄現在時間到該時間點的間隔秒數,記錄sleep

(3)time.process_time()   隨意選取一個時間點,記錄現在時間到該時間點的間隔秒數,不記錄sleep

perf_counter()精度較time()更高一些

t_1_start = time.time()
t_2_start = time.perf_counter()
t_3_start = time.process_time()
print(t_1_start)
print(t_2_start)
print(t_3_start)

res = 0
for i in range(1000000):
    res += i
    9
time.sleep(5)
t_1_end = time.time()
t_2_end = time.perf_counter()
t_3_end = time.process_time()

print("time方法:{:.3f}秒".format(t_1_end-t_1_start))
print("perf_counter方法:{:.3f}秒".format(t_2_end-t_2_start))
print("process_time方法:{:.3f}秒".format(t_3_end-t_3_start))
1567068710.7269545
6009.0814064
2.25
time方法:5.128秒
perf_counter方法:5.128秒
process_time方法:0.125秒

3、格式化輸出

(1)time.strftime 自定義格式化輸出

lctime = time.localtime()
time.strftime("%Y-%m-%d %A %H:%M:%S", lctime)
'2020-02-03 Monday 22:59:09'

4、睡覺覺

(1)time.sleep()

10.2 random庫

隨機數在計算機應用中十分常見

Python通過random庫提供各種僞隨機數

基本可以用於除加密解密算法外的大多數工程應用

1、隨機種子——seed(a=None)

(1)相同種子會產生相同的隨機數

(2)如果不設置隨機種子,以系統當前時間爲默認值

from random import *

seed(10)
print(random())
seed(10)
print(random())
0.5714025946899135
0.5714025946899135
print(random())
0.4288890546751146

2、產生隨機整數

(1)randint(a, b)——產生[a, b]之間的隨機整數(其中a和b都可以取到,左閉右閉區間)

numbers = [randint(1,10) for i in range(10)]
numbers
[10, 1, 4, 8, 8, 5, 3, 1, 9, 8]

(2)randrange(a)——產生[0, a)之間的隨機整數,(不包含a,左閉右開區間)

numbers = [randrange(10) for i in range(10)]
numbers
[5, 1, 3, 5, 0, 6, 2, 9, 5, 6]

(3)randrange(a, b, step)——產生[a, b)之間以setp爲步長的隨機整數

numbers = [randrange(0, 10, 2) for i in range(10)]
numbers
[6, 4, 4, 6, 2, 4, 4, 2, 6, 2]

3、產生隨機浮點數

(1)random()——產生[0.0, 1.0)之間的隨機浮點數

numbers = [random() for i in range(10)]
numbers
[0.9693881604049188,
 0.613326820546709,
 0.0442606328646209,
 0.004055144158407464,
 0.13397252704913387,
 0.941002271395834,
 0.3028605620290723,
 0.3661456016604264,
 0.8981962445391883,
 0.31436380495645067]

(2)uniform(a, b)——產生[a, b]之間的隨機浮點數

numbers = [uniform(2.1, 3.5) for i in range(10)]
numbers
[2.8685750576173676,
 2.710443340673771,
 2.190991846577591,
 2.9183647159827024,
 3.281695056726663,
 2.318986485742369,
 2.414018556160458,
 2.678018290800777,
 2.1516948166820806,
 2.7952448980631672]

4、序列用函數

(1)choice(seq)——從目標序列類型中隨機返回一個元素

choice(['win', 'lose', 'draw'])
'draw'
choice("python")
'n'

(2)choices(seq,weights=None, k)——對序列類型進行k次重複採樣,可設置權重,權重小的說明被取到的概率更小

choices(['win', 'lose', 'draw'], k=5)
['win', 'draw', 'win', 'lose', 'draw']
choices(['win', 'lose', 'draw'], [4,4,2], k=10) # 這裏的[4,4,2]就是每個元素分別對應的權重
['draw', 'win', 'draw', 'lose', 'lose', 'draw', 'win', 'win', 'draw', 'lose']

(3)shuffle(seq)——將序列類型中元素隨機排列,返回打亂後的序列

numbers = ["one", "two", "three", "four"]
shuffle(numbers)
numbers
['two', 'four', 'one', 'three']

(4)sample(pop, k)——從pop類型中隨機選取k個元素,以列表類型返回,如果k大於所有元素的個數,則報錯

sample([10, 20, 30, 40, 50], k=3)
[20, 30, 10]

5、概率分佈——以高斯分佈爲例

gauss(mean, std)——生產一個符合高斯分佈的隨機數,mean–均值,std–標準差

number = gauss(0, 1)
number
0.6331522345532208

多生成幾個

import matplotlib.pyplot as plt

res = [gauss(0, 1) for i in range(100000)]

plt.hist(res, bins=1000)
plt.show()

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-DVFQYiMF-1581131470731)(output_49_0.png)]

【例1】用random庫實現簡單的微信紅包分配

import random


def red_packet(total, num):
    for i in range(1, num):
        per = random.uniform(0.01, total/(num-i+1)*2)          # 保證每個人獲得紅包的期望是total/num
        total = total - per
        print("第{}位紅包金額: {:.2f}元".format(i, per))
    else:
        print("第{}位紅包金額: {:.2f}元".format(num, total))
            
            
red_packet(10, 5)
第1位紅包金額: 1.85元
第2位紅包金額: 3.90元
第3位紅包金額: 0.41元
第4位紅包金額: 3.30元
第5位紅包金額: 0.54元
import random
import numpy as np


def red_packet(total, num):
    ls = []
    for i in range(1, num):
        per = round(random.uniform(0.01, total/(num-i+1)*2), 2)     # 保證每個人獲得紅包的期望是total/num
        ls.append(per)
        total = total - per
    else:
        ls.append(total)
        
    return ls
            
            
# 重複發十萬次紅包,統計每個位置的平均值(約等於期望)
res = []
for i in range(100000):
    ls = red_packet(10,5)
    res.append(ls)

res = np.array(res)
print(res[:10])
np.mean(res, axis=0)
[[1.71 1.57 0.36 1.25 5.11]
 [1.96 0.85 1.46 3.29 2.44]
 [3.34 0.27 1.9  0.64 3.85]
 [1.99 1.08 3.86 1.69 1.38]
 [1.56 1.47 0.66 4.09 2.22]
 [0.57 0.44 1.87 5.81 1.31]
 [0.47 1.41 3.97 1.28 2.87]
 [2.65 1.82 1.22 2.02 2.29]
 [3.16 1.2  0.3  3.66 1.68]
 [2.43 0.16 0.11 0.79 6.51]]





array([1.9991849, 2.0055725, 2.0018144, 2.0022472, 1.991181 ])

【例2】生產4位由數字和英文字母構成的驗證碼

import random
import string

print(string.digits)
print(string.ascii_letters)

s=string.digits + string.ascii_letters
v=random.sample(s,4)
print(v)
print(''.join(v))
0123456789
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
['n', 'Q', '4', '7']
nQ47

10.3 collections庫——容器數據類型

(組合數據類型的擴展)

import collections

1、namedtuple——具名元組

  • 點的座標,僅看數據,很難知道表達的是一個點的座標
p = (1, 2)
  • 構建一個新的元組子類

    定義方法如下:typename 是元組名字,field_names 是域名

collections.namedtuple(typename, field_names, *, rename=False, defaults=None, module=None)
Point = collections.namedtuple("Point", ["x", "y"])
p = Point(1, y=2)
p
Point(x=1, y=2)
  • 可以調用屬性
print(p.x)
print(p.y)
1
2
  • 有元組的性質
print(p[0])
print(p[1])
x, y = p
print(x)
print(y)
1
2
1
2
  • 確實是元組的子類
print(isinstance(p, tuple))
True

【例】模擬撲克牌

Card = collections.namedtuple("Card", ["rank", "suit"])
ranks = [str(n) for n in range(2, 11)] + list("JQKA")    
suits = "spades diamonds clubs hearts".split()
print("ranks", ranks)
print("suits", suits)
cards = [Card(rank, suit) for rank in ranks
                          for suit in suits]
cards
ranks ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']
suits ['spades', 'diamonds', 'clubs', 'hearts']





[Card(rank='2', suit='spades'),
 Card(rank='2', suit='diamonds'),
 Card(rank='2', suit='clubs'),
 Card(rank='2', suit='hearts'),
 Card(rank='3', suit='spades'),
 Card(rank='3', suit='diamonds'),
 Card(rank='3', suit='clubs'),
 Card(rank='3', suit='hearts'),
 Card(rank='4', suit='spades'),
 Card(rank='4', suit='diamonds'),
 Card(rank='4', suit='clubs'),
 Card(rank='4', suit='hearts'),
 Card(rank='5', suit='spades'),
 Card(rank='5', suit='diamonds'),
 Card(rank='5', suit='clubs'),
 Card(rank='5', suit='hearts'),
 Card(rank='6', suit='spades'),
 Card(rank='6', suit='diamonds'),
 Card(rank='6', suit='clubs'),
 Card(rank='6', suit='hearts'),
 Card(rank='7', suit='spades'),
 Card(rank='7', suit='diamonds'),
 Card(rank='7', suit='clubs'),
 Card(rank='7', suit='hearts'),
 Card(rank='8', suit='spades'),
 Card(rank='8', suit='diamonds'),
 Card(rank='8', suit='clubs'),
 Card(rank='8', suit='hearts'),
 Card(rank='9', suit='spades'),
 Card(rank='9', suit='diamonds'),
 Card(rank='9', suit='clubs'),
 Card(rank='9', suit='hearts'),
 Card(rank='10', suit='spades'),
 Card(rank='10', suit='diamonds'),
 Card(rank='10', suit='clubs'),
 Card(rank='10', suit='hearts'),
 Card(rank='J', suit='spades'),
 Card(rank='J', suit='diamonds'),
 Card(rank='J', suit='clubs'),
 Card(rank='J', suit='hearts'),
 Card(rank='Q', suit='spades'),
 Card(rank='Q', suit='diamonds'),
 Card(rank='Q', suit='clubs'),
 Card(rank='Q', suit='hearts'),
 Card(rank='K', suit='spades'),
 Card(rank='K', suit='diamonds'),
 Card(rank='K', suit='clubs'),
 Card(rank='K', suit='hearts'),
 Card(rank='A', suit='spades'),
 Card(rank='A', suit='diamonds'),
 Card(rank='A', suit='clubs'),
 Card(rank='A', suit='hearts')]
from random import *
# 洗牌
shuffle(cards)
cards
[Card(rank='J', suit='hearts'),
 Card(rank='A', suit='hearts'),
 Card(rank='3', suit='hearts'),
 Card(rank='8', suit='hearts'),
 Card(rank='K', suit='hearts'),
 Card(rank='7', suit='spades'),
 Card(rank='5', suit='hearts'),
 Card(rank='A', suit='spades'),
 Card(rank='10', suit='spades'),
 Card(rank='J', suit='diamonds'),
 Card(rank='K', suit='clubs'),
 Card(rank='4', suit='spades'),
 Card(rank='2', suit='diamonds'),
 Card(rank='Q', suit='spades'),
 Card(rank='A', suit='clubs'),
 Card(rank='A', suit='diamonds'),
 Card(rank='6', suit='hearts'),
 Card(rank='7', suit='diamonds'),
 Card(rank='5', suit='diamonds'),
 Card(rank='10', suit='clubs'),
 Card(rank='8', suit='clubs'),
 Card(rank='9', suit='clubs'),
 Card(rank='6', suit='clubs'),
 Card(rank='6', suit='diamonds'),
 Card(rank='5', suit='clubs'),
 Card(rank='3', suit='diamonds'),
 Card(rank='4', suit='hearts'),
 Card(rank='3', suit='clubs'),
 Card(rank='7', suit='hearts'),
 Card(rank='2', suit='spades'),
 Card(rank='J', suit='clubs'),
 Card(rank='9', suit='spades'),
 Card(rank='J', suit='spades'),
 Card(rank='10', suit='hearts'),
 Card(rank='2', suit='clubs'),
 Card(rank='8', suit='diamonds'),
 Card(rank='6', suit='spades'),
 Card(rank='10', suit='diamonds'),
 Card(rank='9', suit='hearts'),
 Card(rank='3', suit='spades'),
 Card(rank='8', suit='spades'),
 Card(rank='Q', suit='clubs'),
 Card(rank='Q', suit='hearts'),
 Card(rank='5', suit='spades'),
 Card(rank='7', suit='clubs'),
 Card(rank='4', suit='clubs'),
 Card(rank='2', suit='hearts'),
 Card(rank='K', suit='diamonds'),
 Card(rank='K', suit='spades'),
 Card(rank='Q', suit='diamonds'),
 Card(rank='4', suit='diamonds'),
 Card(rank='9', suit='diamonds')]
# 隨機抽一張牌
choice(cards)
Card(rank='4', suit='hearts')
# 隨機抽多張牌
sample(cards, k=5)
[Card(rank='4', suit='hearts'),
 Card(rank='2', suit='clubs'),
 Card(rank='Q', suit='diamonds'),
 Card(rank='9', suit='spades'),
 Card(rank='10', suit='hearts')]

2、Counter——計數器工具

from collections import Counter
s = "牛奶奶找劉奶奶買牛奶"
colors = ['red', 'blue', 'red', 'green', 'blue', 'blue']
cnt_str = Counter(s)
cnt_color = Counter(colors)
print(cnt_str)
print(cnt_color)
Counter({'奶': 5, '牛': 2, '找': 1, '劉': 1, '買': 1})
Counter({'blue': 3, 'red': 2, 'green': 1})
  • 是字典的一個子類
print(isinstance(Counter(), dict))
True
  • 最常見的統計——most_commom(n)
    提供 n 個頻率最高的元素和計數
cnt_color.most_common(2)
[('blue', 3), ('red', 2)]
  • 元素展開——elements()
list(cnt_str.elements())
['牛', '牛', '奶', '奶', '奶', '奶', '奶', '找', '劉', '買']
  • 其他一些加減操作
c = Counter(a=3, b=1)
d = Counter(a=1, b=2)
c+d
Counter({'a': 4, 'b': 3})

【例】從一副牌中抽取10張,大於10的比例有多少

cards = collections.Counter(tens=16, low_cards=36)
seen = sample(list(cards.elements()), k=10)
print(seen)
['tens', 'low_cards', 'low_cards', 'low_cards', 'tens', 'tens', 'low_cards', 'low_cards', 'low_cards', 'low_cards']
seen.count('tens') / 10
0.3

3、deque——雙向隊列

列表訪問數據非常快速

插入和刪除操作非常慢——通過移動元素位置來實現

特別是 insert(0, v) 和 pop(0),在列表開始進行的插入和刪除操作

雙向隊列可以方便的在隊列兩邊高效、快速的增加和刪除元素

from collections import deque

d = deque('cde') 
d
deque(['c', 'd', 'e'])
d.append("f")            # 右端增加
d.append("g")
d.appendleft("b")        # 左端增加
d.appendleft("a")
d
deque(['a', 'b', 'c', 'd', 'e', 'f', 'g'])
d.pop()           # 右端刪除 
d.popleft()       # 左端刪除
d
deque(['b', 'c', 'd', 'e', 'f'])

deque 其他用法可參考官方文檔

10.4 itertools庫——迭代器

1、排列組合迭代器

(1)product——笛卡爾積

import itertools

for i in itertools.product('ABC', '01'):
    print(i)
('A', '0')
('A', '1')
('B', '0')
('B', '1')
('C', '0')
('C', '1')
for i in itertools.product('ABC', repeat=3):  # 這裏就相當於有三個‘ABC’
    print(i)
('A', 'A', 'A')
('A', 'A', 'B')
('A', 'A', 'C')
('A', 'B', 'A')
('A', 'B', 'B')
('A', 'B', 'C')
('A', 'C', 'A')
('A', 'C', 'B')
('A', 'C', 'C')
('B', 'A', 'A')
('B', 'A', 'B')
('B', 'A', 'C')
('B', 'B', 'A')
('B', 'B', 'B')
('B', 'B', 'C')
('B', 'C', 'A')
('B', 'C', 'B')
('B', 'C', 'C')
('C', 'A', 'A')
('C', 'A', 'B')
('C', 'A', 'C')
('C', 'B', 'A')
('C', 'B', 'B')
('C', 'B', 'C')
('C', 'C', 'A')
('C', 'C', 'B')
('C', 'C', 'C')

(2) permutations——排列

for i in itertools.permutations('ABCD', 3):   # ABC中取三個進行排列
    print(i)
('A', 'B', 'C')
('A', 'B', 'D')
('A', 'C', 'B')
('A', 'C', 'D')
('A', 'D', 'B')
('A', 'D', 'C')
('B', 'A', 'C')
('B', 'A', 'D')
('B', 'C', 'A')
('B', 'C', 'D')
('B', 'D', 'A')
('B', 'D', 'C')
('C', 'A', 'B')
('C', 'A', 'D')
('C', 'B', 'A')
('C', 'B', 'D')
('C', 'D', 'A')
('C', 'D', 'B')
('D', 'A', 'B')
('D', 'A', 'C')
('D', 'B', 'A')
('D', 'B', 'C')
('D', 'C', 'A')
('D', 'C', 'B')
for i in itertools.permutations(range(3)):
    print(i)
(0, 1, 2)
(0, 2, 1)
(1, 0, 2)
(1, 2, 0)
(2, 0, 1)
(2, 1, 0)

(3)combinations——組合

for i in itertools.combinations('ABC', 2):  # ABC中取2個進行組合,元素不可重複
    print(i)
('A', 'B')
('A', 'C')
('B', 'C')
for i in itertools.combinations(range(4), 3):
    print(i)
(0, 1, 2)
(0, 1, 3)
(0, 2, 3)
(1, 2, 3)

(4)combinations_with_replacement——元素可重複組合

for i in itertools.combinations_with_replacement('ABC', 2):  # ABC中取2個進行組合,元素可重複
    print(i)
('A', 'A')
('A', 'B')
('A', 'C')
('B', 'B')
('B', 'C')
('C', 'C')
for i in itertools.product('ABC',repeat=2):
    print(i)
('A', 'A')
('A', 'B')
('A', 'C')
('B', 'A')
('B', 'B')
('B', 'C')
('C', 'A')
('C', 'B')
('C', 'C')

2、拉鍊

(1)zip——短拉鍊

for i in zip("ABC", "012", "xyz"): # 相同位置的元素組合到一起
    print(i)
('A', '0', 'x')
('B', '1', 'y')
('C', '2', 'z')

長度不一時,執行到最短的對象處,就停止

for i in zip("ABC", [0, 1, 2, 3, 4, 5]):          # 注意zip是內置的,不需要加itertools
    print(i)
('A', 0)
('B', 1)
('C', 2)

(2)zip_longest——長拉鍊

長度不一時,執行到最長的對象處,就停止,缺省元素用None或指定字符替代

for i in itertools.zip_longest("ABC", "012345"):
    print(i)
('A', '0')
('B', '1')
('C', '2')
(None, '3')
(None, '4')
(None, '5')
for i in itertools.zip_longest("ABC", "012345", fillvalue = "?"):
    print(i)
('A', '0')
('B', '1')
('C', '2')
('?', '3')
('?', '4')
('?', '5')

3、無窮迭代器

(1)count(start=0, step=1)——計數

創建一個迭代器,它從 start 值開始,返回均勻間隔的值
itertools.count(10)
10
11
12
.
.
.

(2)cycle(iterable)——循環

創建一個迭代器,返回 iterable 中所有元素,無限重複
itertools.cycle("ABC")
A
B
C
A
B
C
.
.
.

(3)repeat(object [, times])——重複

創建一個迭代器,不斷重複 object 。除非設定參數 times ,否則將無限重複
for i in itertools.repeat(10, 3): #這裏設置3,表示會重複3次,如果沒有設置,則會無限重複
    print(i)
10
10
10

4、其他

(1)chain(iterables)——鎖鏈

把一組迭代對象串聯起來,形成一個更大的迭代器
for i in itertools.chain('ABC', [1, 2, 3]):
    print(i)
A
B
C
1
2
3

(2)enumerate(iterable, start=0)——枚舉(Python內置)

產出由兩個元素組成的元組,結構是(index, item),其中index 從start開始,item從iterable中取
for i in enumerate("Python", start=1):
    print(i)
(1, 'P')
(2, 'y')
(3, 't')
(4, 'h')
(5, 'o')
(6, 'n')

(3)groupby(iterable, key=None)——分組

創建一個迭代器,按照key指定的方式,返回 iterable 中連續的鍵和組
一般來說,要預先對數據進行排序
key爲None默認把連續重複元素分組
for key, group in itertools.groupby('AAAABBBCCDAABBB'):
    print(key, list(group))
A ['A', 'A', 'A', 'A']
B ['B', 'B', 'B']
C ['C', 'C']
D ['D']
A ['A', 'A']
B ['B', 'B', 'B']
animals = ["duck", "eagle", "rat", "giraffe", "bear", "bat", "dolphin", "shark", "lion"]
animals.sort(key=len)
print(animals)
['rat', 'bat', 'duck', 'bear', 'lion', 'eagle', 'shark', 'giraffe', 'dolphin']
for key, group in itertools.groupby(animals, key=len):
    print(key, list(group))
3 ['rat', 'bat']
4 ['duck', 'bear', 'lion']
5 ['eagle', 'shark']
7 ['giraffe', 'dolphin']
animals = ["duck", "eagle", "rat", "giraffe", "bear", "bat", "dolphin", "shark", "lion"]
animals.sort(key=lambda x: x[0])
print(animals)
for key, group in itertools.groupby(animals, key=lambda x: x[0]):
    print(key, list(group))
['bear', 'bat', 'duck', 'dolphin', 'eagle', 'giraffe', 'lion', 'rat', 'shark']
b ['bear', 'bat']
d ['duck', 'dolphin']
e ['eagle']
g ['giraffe']
l ['lion']
r ['rat']
s ['shark']

itertools 其他函數可參考官方文檔

發佈了24 篇原創文章 · 獲贊 32 · 訪問量 1475
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章