本文推薦一個python的傻瓜式的學習資源,內容簡單易懂,讓人可以在60 秒學會一個 Python 小例子
當前庫已有 300多 個實用的小例子
本文來源:https://github.com/jackzhenguo/python-small-examples
文章轉自:機器學習初學者
本庫目錄第一章:Python 基礎
第二章:Python字符串+正則
第三章:Python文件日期和多線程
第四章:Python三大利器
第五章:Python繪圖
第六章:Python之坑
第七章:Python第三方包
第八章:必知算法
第九章:Python實戰
第十章:數據分析
第十一章:一步一步掌握Flask web開發
部分內容(1-90) 一、Python基礎Python基礎主要總結Python常用內置函數;Python獨有的語法特性、關鍵詞nonlocal, global等;內置數據結構包括:列表(list), 字典(dict), 集合(set), 元組(tuple) 以及相關的高級模塊collections中的Counter, namedtuple, defaultdict,heapq模塊。目前共有90個小例子。
1 求絕對值絕對值或複數的模
In [1]: abs(-6)
Out[1]: 6
2 元素都為真接受一個可迭代對象,如果可迭代對象的所有元素都為真,那麼返回 True,否則返回False
In [2]: all([1,0,3,6])
Out[2]: False
In [3]: all([1,2,3])
Out[3]: True
3 元素至少一個為真接受一個可迭代對象,如果可迭代對象裡至少有一個元素為真,那麼返回True,否則返回False
In [4]: any([0,0,0,[]])
Out[4]: False
In [5]: any([0,0,1])
Out[5]: True
4 ascii展示對象調用對象的 _repr_ 方法,獲得該方法的返回值,如下例子返回值為字符串
In [1]: class Student():
...: def __init__(self,id,name):
...: self.id = id
...: self.name = name
...: def __repr__(self):
...: return 'id = '+self.id +', name = '+self.name
...:
...:
In [2]: xiaoming = Student(id='001',name='xiaoming')
In [3]: print(xiaoming)
id = 001, name = xiaoming
In [4]: ascii(xiaoming)
Out[4]: 'id = 001, name = xiaoming'
5 十轉二將十進位轉換為二進位
In [1]: bin(10)
Out[1]: '0b1010'
6 十轉八將十進位轉換為八進位
In [1]: oct(9)
Out[1]: '0o11'
7 十轉十六將十進位轉換為十六進位
In [1]: hex(15)
Out[1]: '0xf'
8 判斷是真是假測試一個對象是True, 還是False.
In [1]: bool([0,0,0])
Out[1]: True
In [2]: bool([])
Out[2]: False
In [3]: bool([1,0,1])
Out[3]: True
9 字符串轉字節將一個字符串轉換成字節類型
In [1]: s = "apple"
In [2]: bytes(s,encoding='utf-8')
Out[2]: b'apple'
10 轉為字符串將字符類型、數值類型等轉換為字符串類型
In [1]: i = 100
In [2]: str(i)
Out[2]: '100'
11 是否可調用判斷對象是否可被調用,能被調用的對象就是一個callable 對象,比如函數 str, int 等都是可被調用的,但是例子4 中xiaoming實例是不可被調用的:
In [1]: callable(str)
Out[1]: True
In [2]: callable(int)
Out[2]: True
In [3]: xiaoming
Out[3]: id = 001, name = xiaoming
In [4]: callable(xiaoming)
Out[4]: False如果想讓xiaoming能被調用 xiaoming(), 需要重寫Student類的__call__方法:
In [1]: class Student():
...: def __init__(self,id,name):
...: self.id = id
...: self.name = name
...: def __repr__(self):
...: return 'id = '+self.id +', name = '+self.name
...: def __call__(self):
...: print('I can be called')
...: print(f'my name is {self.name}')
...:
...:
In [2]: t = Student('001','xiaoming')
In [3]: t()
I can be called
my name is xiaoming
12 十轉ASCII查看十進位整數對應的ASCII字符
In [1]: chr(65)
Out[1]: 'A'
13 ASCII轉十查看某個ASCII字符對應的十進位數
In [1]: ord('A')
Out[1]: 65
14 類方法classmethod 裝飾器對應的函數不需要實例化,不需要 self參數,但第一個參數需要是表示自身類的 cls 參數,可以來調用類的屬性,類的方法,實例化對象等。
In [1]: class Student():
...: def __init__(self,id,name):
...: self.id = id
...: self.name = name
...: def __repr__(self):
...: return 'id = '+self.id +', name = '+self.name
...: @classmethod
...: def f(cls):
...: print(cls)
15 執行字符串表示的代碼將字符串編譯成python能識別或可執行的代碼,也可以將文字讀成字符串再編譯。
In [1]: s = "print('helloworld')"
In [2]: r = compile(s,"<string>", "exec")
In [3]: r
Out[3]: <code object <module> at 0x0000000005DE75D0, file "<string>", line 1>
In [4]: exec(r)
helloworld
16 創建複數創建一個複數
In [1]: complex(1,2)
Out[1]: (1+2j)
17 動態刪除屬性刪除對象的屬性
In [1]: delattr(xiaoming,'id')
In [2]: hasattr(xiaoming,'id')
Out[2]: False
18 轉為字典創建數據字典
In [1]: dict()
Out[1]: {}
In [2]: dict(a='a',b='b')
Out[2]: {'a': 'a', 'b': 'b'}
In [3]: dict(zip(['a','b'],[1,2]))
Out[3]: {'a': 1, 'b': 2}
In [4]: dict([('a',1),('b',2)])
Out[4]: {'a': 1, 'b': 2}
19 一鍵查看對象所有方法不帶參數時返回當前範圍內的變量、方法和定義的類型列表;帶參數時返回參數的屬性,方法列表。
In [96]: dir(xiaoming)
Out[96]:
['__class__',
'__delattr__',
'__dict__',
'__dir__',
'__doc__',
'__eq__',
'__format__',
'__ge__',
'__getattribute__',
'__gt__',
'__hash__',
'__init__',
'__init_subclass__',
'__le__',
'__lt__',
'__module__',
'__ne__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__setattr__',
'__sizeof__',
'__str__',
'__subclasshook__',
'__weakref__',
'name']
20 取商和餘數分別取商和餘數
In [1]: divmod(10,3)
Out[1]: (3, 1)
21 枚舉對象返回一個可以枚舉的對象,該對象的next()方法將返回一個元組。
In [1]: s = ["a","b","c"]
...: for i ,v in enumerate(s,1):
...: print(i,v)
...:
1 a
2 b
3 c
22 計算表達式將字符串str 當成有效的表達式來求值並返回計算結果取出字符串中內容
In [1]: s = "1 + 3 +5"
...: eval(s)
...:
Out[1]: 9
23 查看變量所佔字節數In [1]: import sys
In [2]: a = {'a':1,'b':2.0}
In [3]: sys.getsizeof(a) # 佔用240個字節
Out[3]: 240
24 過濾器在函數中設定過濾條件,迭代元素,保留返回值為True的元素:
In [1]: fil = filter(lambda x: x>10,[1,11,2,45,7,6,13])
In [2]: list(fil)
Out[2]: [11, 45, 13]
25 轉為浮點類型將一個整數或數值型字符串轉換為浮點數
In [1]: float(3)
Out[1]: 3.0如果不能轉化為浮點數,則會報ValueError:
In [2]: float('a')
# ValueError: could not convert string to float: 'a'
26 字符串格式化格式化輸出字符串,format(value, format_spec)實質上是調用了value的__format__(format_spec)方法。
In [104]: print("i am {0},age{1}".format("tom",18))
i am tom,age18
3.1415926{:.2f}3.14保留小數點後兩位3.1415926{:+.2f}+3.14帶符號保留小數點後兩位-1{:+.2f}-1.00帶符號保留小數點後兩位2.71828{:.0f}3不帶小數5{:0>2d}05數字補零 (填充左邊, 寬度為2)5{:x<4d}5xxx數字補x (填充右邊, 寬度為4)10{:x<4d}10xx數字補x (填充右邊, 寬度為4)1000000{:,}1,000,000以逗號分隔的數字格式0.25{:.2%}25.00%百分比格式1000000000{:.2e}1.00e+09指數記法18{:>10d}' 18'右對齊 (默認, 寬度為10)18{:<10d}'18 '左對齊 (寬度為10)18{:^10d}' 18 '中間對齊 (寬度為10)27 凍結集合創建一個不可修改的集合。
In [1]: frozenset([1,1,3,2,3])
Out[1]: frozenset({1, 2, 3})因為不可修改,所以沒有像set那樣的add和pop方法
28 動態獲取對象屬性獲取對象的屬性
In [1]: class Student():
...: def __init__(self,id,name):
...: self.id = id
...: self.name = name
...: def __repr__(self):
...: return 'id = '+self.id +', name = '+self.name
In [2]: xiaoming = Student(id='001',name='xiaoming')
In [3]: getattr(xiaoming,'name') # 獲取xiaoming這個實例的name屬性值
Out[3]: 'xiaoming'
29 對象是否有這個屬性In [1]: class Student():
...: def __init__(self,id,name):
...: self.id = id
...: self.name = name
...: def __repr__(self):
...: return 'id = '+self.id +', name = '+self.name
In [2]: xiaoming = Student(id='001',name='xiaoming')
In [3]: hasattr(xiaoming,'name')
Out[3]: True
In [4]: hasattr(xiaoming,'address')
Out[4]: False
30 返回對象的哈希值返回對象的哈希值,值得注意的是自定義的實例都是可哈希的,list, dict, set等可變對象都是不可哈希的(unhashable)
In [1]: hash(xiaoming)
Out[1]: 6139638
In [2]: hash([1,2,3])
# TypeError: unhashable type: 'list'
31 一鍵幫助返回對象的幫助文檔
In [1]: help(xiaoming)
Help on Student in module __main__ object:
class Student(builtins.object)
| Methods defined here:
|
| __init__(self, id, name)
|
| __repr__(self)
|
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)
32 對象門牌號返回對象的內存地址
In [1]: id(xiaoming)
Out[1]: 98234208
33 獲取用戶輸入獲取用戶輸入內容
In [1]: input()
aa
Out[1]: 'aa'
34 轉為整型int(x, base =10) , x可能為字符串或數值,將x 轉換為一個普通整數。如果參數是字符串,那麼它可能包含符號和小數點。如果超出了普通整數的表示範圍,一個長整數被返回。
In [1]: int('12',16)
Out[1]: 18
35 isinstance判斷object是否為類classinfo的實例,是返回true
In [1]: class Student():
...: def __init__(self,id,name):
...: self.id = id
...: self.name = name
...: def __repr__(self):
...: return 'id = '+self.id +', name = '+self.name
In [2]: xiaoming = Student(id='001',name='xiaoming')
In [3]: isinstance(xiaoming,Student)
Out[3]: True
36 父子關係鑑定In [1]: class undergraduate(Student):
...: def studyClass(self):
...: pass
...: def attendActivity(self):
...: pass
In [2]: issubclass(undergraduate,Student)
Out[2]: True
In [3]: issubclass(object,Student)
Out[3]: False
In [4]: issubclass(Student,object)
Out[4]: True如果class是classinfo元組中某個元素的子類,也會返回True
In [1]: issubclass(int,(int,float))
Out[1]: True
37 創建迭代器類型使用iter(obj, sentinel), 返回一個可迭代對象, sentinel可省略(一旦迭代到此元素,立即終止)
In [1]: lst = [1,3,5]
In [2]: for i in iter(lst):
...: print(i)
...:
1
3
5In [1]: class TestIter(object):
...: def __init__(self):
...: self.l=[1,3,2,3,4,5]
...: self.i=iter(self.l)
...: def __call__(self): #定義了__call__方法的類的實例是可調用的
...: item = next(self.i)
...: print ("__call__ is called,fowhich would return",item)
...: return item
...: def __iter__(self): #支持迭代協議(即定義有__iter__()函數)
...: print ("__iter__ is called!!")
...: return iter(self.l)
In [2]: t = TestIter()
In [3]: t() # 因為實現了__call__,所以t實例能被調用
__call__ is called,which would return 1
Out[3]: 1
In [4]: for e in TestIter(): # 因為實現了__iter__方法,所以t能被迭代
...: print(e)
...:
__iter__ is called!!
1
3
2
3
4
5
38 所有對象之根object 是所有類的基類
In [1]: o = object()
In [2]: type(o)
Out[2]: object
39 打開文件返回文件對象
In [1]: fo = open('D:/a.txt',mode='r', encoding='utf-8')
In [2]: fo.read()
Out[2]: '\ufefflife is not so long,\nI use Python to play.'mode取值表:
字符意義'r'讀取(默認)'w'寫入,並先截斷文件'x'排它性創建,如果文件已存在則失敗'a'寫入,如果文件存在則在末尾追加'b'二進位模式't'文本模式(默認)'+'打開用於更新(讀取與寫入)40 次冪base為底的exp次冪,如果mod給出,取餘
In [1]: pow(3, 2, 4)
Out[1]: 1
41 列印In [5]: lst = [1,3,5]
In [6]: print(lst)
[1, 3, 5]
In [7]: print(f'lst: {lst}')
lst: [1, 3, 5]
In [8]: print('lst:{}'.format(lst))
lst:[1, 3, 5]
In [9]: print('lst:',lst)
lst: [1, 3, 5]
42 創建屬性的兩種方式返回 property 屬性,典型的用法:
class C:
def __init__(self):
self._x = None
def getx(self):
return self._x
def setx(self, value):
self._x = value
def delx(self):
del self._x
# 使用property類創建 property 屬性
x = property(getx, setx, delx, "I'm the 'x' property.")使用python裝飾器,實現與上完全一樣的效果代碼:
class C:
def __init__(self):
self._x = None
@property
def x(self):
return self._x
@x.setter
def x(self, value):
self._x = value
@x.deleter
def x(self):
del self._x
43 創建range序列range(start, stop[,step])生成一個不可變序列:
In [1]: range(11)
Out[1]: range(0, 11)
In [2]: range(0,11,1)
Out[2]: range(0, 11)
44 反向迭代器In [1]: rev = reversed([1,4,2,3,1])
In [2]: for i in rev:
...: print(i)
...:
1
3
2
4
1
45 四捨五入四捨五入,ndigits代表小數點後保留幾位:
In [11]: round(10.0222222, 3)
Out[11]: 10.022
In [12]: round(10.05,1)
Out[12]: 10.1
46 轉為集合類型返回一個set對象,集合內不允許有重複元素:
In [159]: a = [1,4,2,3,1]
In [160]: set(a)
Out[160]: {1, 2, 3, 4}
47 轉為切片對象class slice(start, stop[, step])
返回一個表示由 range(start, stop, step) 所指定索引集的 slice對象,它讓代碼可讀性、可維護性變好。
In [1]: a = [1,4,2,3,1]
In [2]: my_slice_meaning = slice(0,5,2)
In [3]: a[my_slice_meaning]
Out[3]: [1, 2, 1]
48 拿來就用的排序函數排序:
In [1]: a = [1,4,2,3,1]
In [2]: sorted(a,reverse=True)
Out[2]: [4, 3, 2, 1, 1]
In [3]: a = [{'name':'xiaoming','age':18,'gender':'male'},{'name':'
...: xiaohong','age':20,'gender':'female'}]
In [4]: sorted(a,key=lambda x: x['age'],reverse=False)
Out[4]:
[{'name': 'xiaoming', 'age': 18, 'gender': 'male'},
{'name': 'xiaohong', 'age': 20, 'gender': 'female'}]####49 求和函數
求和:
In [181]: a = [1,4,2,3,1]
In [182]: sum(a)
Out[182]: 11
In [185]: sum(a,10) #求和的初始值為10
Out[185]: 21
50 轉元組tuple() 將對象轉為一個不可變的序列類型
In [16]: i_am_list = [1,3,5]
In [17]: i_am_tuple = tuple(i_am_list)
In [18]: i_am_tuple
Out[18]: (1, 3, 5)
51 查看對象類型class type(name, bases, dict)
傳入一個參數時,返回 object 的類型:
In [1]: class Student():
...: def __init__(self,id,name):
...: self.id = id
...: self.name = name
...: def __repr__(self):
...: return 'id = '+self.id +', name = '+self.name
...:
...:
In [2]: xiaoming = Student(id='001',name='xiaoming')
In [3]: type(xiaoming)
Out[3]: __main__.Student
In [4]: type(tuple())
Out[4]: tuple
52 聚合迭代器創建一個聚合了來自每個可迭代對象中的元素的迭代器:
In [1]: x = [3,2,1]
In [2]: y = [4,5,6]
In [3]: list(zip(y,x))
Out[3]: [(4, 3), (5, 2), (6, 1)]
In [4]: a = range(5)
In [5]: b = list('abcde')
In [6]: b
Out[6]: ['a', 'b', 'c', 'd', 'e']
In [7]: [str(y) + str(x) for x,y in zip(a,b)]
Out[7]: ['a0', 'b1', 'c2', 'd3', 'e4']
53 nonlocal用於內嵌函數中關鍵詞nonlocal常用於函數嵌套中,聲明變量i為非局部變量;如果不聲明,i+=1表明i為函數wrapper內的局部變量,因為在i+=1引用(reference)時,i未被聲明,所以會報unreferenced variable的錯誤。
def excepter(f):
i = 0
t1 = time.time()
def wrapper():
try:
f()
except Exception as e:
nonlocal i
i += 1
print(f'{e.args[0]}: {i}')
t2 = time.time()
if i == n:
print(f'spending time:{round(t2-t1,2)}')
return wrapper
54 global 聲明全局變量先回答為什麼要有global,一個變量被多個函數引用,想讓全局變量被所有函數共享。有的夥伴可能會想這還不簡單,這樣寫:
i = 5
def f():
print(i)
def g():
print(i)
pass
f()
g()f和g兩個函數都能共享變量i,程序沒有報錯,所以他們依然不明白為什麼要用global.
但是,如果我想要有個函數對i遞增,這樣:
def h():
i += 1
h()此時執行程序,bang, 出錯了!拋出異常:UnboundLocalError,原來編譯器在解釋i+=1時會把i解析為函數h()內的局部變量,很顯然在此函數內,編譯器找不到對變量i的定義,所以會報錯。
global就是為解決此問題而被提出,在函數h內,顯示地告訴編譯器i為全局變量,然後編譯器會在函數外面尋找i的定義,執行完i+=1後,i還為全局變量,值加1:
i = 0
def h():
global i
i += 1
h()
print(i)
55 鏈式比較i = 3
print(1 < i < 3) # False
print(1 < i <= 3) # True
56 不用else和if實現計算器from operator import *
def calculator(a, b, k):
return {
'+': add,
'-': sub,
'*': mul,
'/': truediv,
'**': pow
}[k](a, b)
calculator(1, 2, '+') # 3
calculator(3, 4, '**') # 81
57 鏈式操作from operator import (add, sub)
def add_or_sub(a, b, oper):
return (add if oper == '+' else sub)(a, b)
add_or_sub(1, 2, '-') # -1
58 交換兩元素def swap(a, b):
return b, a
print(swap(1, 0)) # (0,1)
59 去最求平均def score_mean(lst):
lst.sort()
lst2=lst[1:(len(lst)-1)]
return round((sum(lst2)/len(lst2)),1)
lst=[9.1, 9.0,8.1, 9.7, 19,8.2, 8.6,9.8]
score_mean(lst) # 9.1
60 列印99乘法表列印出如下格式的乘法表
1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
1*4=4 2*4=8 3*4=12 4*4=16
1*5=5 2*5=10 3*5=15 4*5=20 5*5=25
1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36
1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49
1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64
1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81一共有10 行,第i行的第j列等於:j*i,
其中,
i取值範圍:1<=i<=9
j取值範圍:1<=j<=i
根據例子分析的語言描述,轉化為如下代碼:
for i in range(1,10):
...: for j in range(1,i+1):
...: print('%d*%d=%d'%(j,i,j*i),end="\t")
...: print()
61 全展開對於如下數組:
[[[1,2,3],[4,5]]]如何完全展開成一維的。這個小例子實現的flatten是遞歸版,兩個參數分別表示帶展開的數組,輸出數組。
from collections.abc import *
def flatten(lst, out_lst=None):
if out_lst is None:
out_lst = []
for i in lst:
if isinstance(i, Iterable): # 判斷i是否可迭代
flatten(i, out_lst) # 尾數遞歸
else:
out_lst.append(i) # 產生結果
return out_lst調用flatten:
print(flatten([[1,2,3],[4,5]]))
print(flatten([[1,2,3],[4,5]], [6,7]))
print(flatten([[[1,2,3],[4,5,6]]]))
# 結果:
[1, 2, 3, 4, 5]
[6, 7, 1, 2, 3, 4, 5]
[1, 2, 3, 4, 5, 6]numpy裡的flatten與上面的函數實現有些微妙的不同:
import numpy
b = numpy.array([[1,2,3],[4,5]])
b.flatten()
array([list([1, 2, 3]), list([4, 5])], dtype=object)
62 列表等分from math import ceil
def divide(lst, size):
if size <= 0:
return [lst]
return [lst[i * size:(i+1)*size] for i in range(0, ceil(len(lst) / size))]
r = divide([1, 3, 5, 7, 9], 2)
print(r) # [[1, 3], [5, 7], [9]]
r = divide([1, 3, 5, 7, 9], 0)
print(r) # [[1, 3, 5, 7, 9]]
r = divide([1, 3, 5, 7, 9], -3)
print(r) # [[1, 3, 5, 7, 9]]
63 列表壓縮def filter_false(lst):
return list(filter(bool, lst))
r = filter_false([None, 0, False, '', [], 'ok', [1, 2]])
print(r) # ['ok', [1, 2]]
64 更長列表def max_length(*lst):
return max(*lst, key=lambda v: len(v))
r = max_length([1, 2, 3], [4, 5, 6, 7], [8])
print(f'更長的列表是{r}') # [4, 5, 6, 7]
r = max_length([1, 2, 3], [4, 5, 6, 7], [8, 9])
print(f'更長的列表是{r}') # [4, 5, 6, 7]
65 求眾數def top1(lst):
return max(lst, default='列表為空', key=lambda v: lst.count(v))
lst = [1, 3, 3, 2, 1, 1, 2]
r = top1(lst)
print(f'{lst}中出現次數最多的元素為:{r}') # [1, 3, 3, 2, 1, 1, 2]中出現次數最多的元素為:1
66 多表之最def max_lists(*lst):
return max(max(*lst, key=lambda v: max(v)))
r = max_lists([1, 2, 3], [6, 7, 8], [4, 5])
print(r) # 8
67 列表查重def has_duplicates(lst):
return len(lst) == len(set(lst))
x = [1, 1, 2, 2, 3, 2, 3, 4, 5, 6]
y = [1, 2, 3, 4, 5]
has_duplicates(x) # False
has_duplicates(y) # True
68 列表反轉def reverse(lst):
return lst[::-1]
r = reverse([1, -2, 3, 4, 1, 2])
print(r) # [2, 1, 4, 3, -2, 1]
69 浮點數等差數列def rang(start, stop, n):
start,stop,n = float('%.2f' % start), float('%.2f' % stop),int('%.d' % n)
step = (stop-start)/n
lst = [start]
while n > 0:
start,n = start+step,n-1
lst.append(round((start), 2))
return lst
rang(1, 8, 10) # [1.0, 1.7, 2.4, 3.1, 3.8, 4.5, 5.2, 5.9, 6.6, 7.3, 8.0]
70 按條件分組def bif_by(lst, f):
return [ [x for x in lst if f(x)],[x for x in lst if not f(x)]]
records = [25,89,31,34]
bif_by(records, lambda x: x<80) # [[25, 31, 34], [89]]
71 map實現向量運算#多序列運算函數—map(function,iterabel,iterable2)
lst1=[1,2,3,4,5,6]
lst2=[3,4,5,6,3,2]
list(map(lambda x,y:x*y+1,lst1,lst2))
### [4, 9, 16, 25, 16, 13]
72 值最大的字典def max_pairs(dic):
if len(dic) == 0:
return dic
max_val = max(map(lambda v: v[1], dic.items()))
return [item for item in dic.items() if item[1] == max_val]
r = max_pairs({'a': -10, 'b': 5, 'c': 3, 'd': 5})
print(r) # [('b', 5), ('d', 5)]
73 合併兩個字典def merge_dict(dic1, dic2):
return {**dic1, **dic2} # python3.5後支持的一行代碼實現合併字典
merge_dict({'a': 1, 'b': 2}, {'c': 3}) # {'a': 1, 'b': 2, 'c': 3}
74 topn字典from heapq import nlargest
# 返回字典d前n個最大值對應的鍵
def topn_dict(d, n):
return nlargest(n, d, key=lambda k: d[k])
topn_dict({'a': 10, 'b': 8, 'c': 9, 'd': 10}, 3) # ['a', 'd', 'c']
75 異位詞from collections import Counter
# 檢查兩個字符串是否 相同字母異序詞,簡稱:互為變位詞
def anagram(str1, str2):
return Counter(str1) == Counter(str2)
anagram('eleven+two', 'twelve+one') # True 這是一對神器的變位詞
anagram('eleven', 'twelve') # False
76 邏輯上合併字典(1) 兩種合併字典方法這是一般的字典合併寫法
dic1 = {'x': 1, 'y': 2 }
dic2 = {'y': 3, 'z': 4 }
merged1 = {**dic1, **dic2} # {'x': 1, 'y': 3, 'z': 4}修改merged['x']=10,dic1中的x值不變,merged是重新生成的一個新字典。
但是,ChainMap卻不同,它在內部創建了一個容納這些字典的列表。因此使用ChainMap合併字典,修改merged['x']=10後,dic1中的x值改變,如下所示:
from collections import ChainMap
merged2 = ChainMap(dic1,dic2)
print(merged2) # ChainMap({'x': 1, 'y': 2}, {'y': 3, 'z': 4})
77 命名元組提高可讀性from collections import namedtuple
Point = namedtuple('Point', ['x', 'y', 'z']) # 定義名字為Point的元祖,欄位屬性有x,y,z
lst = [Point(1.5, 2, 3.0), Point(-0.3, -1.0, 2.1), Point(1.3, 2.8, -2.5)]
print(lst[0].y - lst[1].y)使用命名元組寫出來的代碼可讀性更好,尤其處理上百上千個屬性時作用更加凸顯。
78 樣本抽樣使用sample抽樣,如下例子從100個樣本中隨機抽樣10個。
from random import randint,sample
lst = [randint(0,50) for _ in range(100)]
print(lst[:5])# [38, 19, 11, 3, 6]
lst_sample = sample(lst,10)
print(lst_sample) # [33, 40, 35, 49, 24, 15, 48, 29, 37, 24]
79 重洗數據集使用shuffle用來重洗數據集,值得注意shuffle是對lst就地(in place)洗牌,節省存儲空間
from random import shuffle
lst = [randint(0,50) for _ in range(100)]
shuffle(lst)
print(lst[:5]) # [50, 3, 48, 1, 26]
80 10個均勻分布的坐標點random模塊中的uniform(a,b)生成[a,b)內的一個隨機數,如下生成10個均勻分布的二維坐標點
from random import uniform
In [1]: [(uniform(0,10),uniform(0,10)) for _ in range(10)]
Out[1]:
[(9.244361194237328, 7.684326645514235),
(8.129267671737324, 9.988395854203773),
(9.505278771040661, 2.8650440524834107),
(3.84320100484284, 1.7687190176304601),
(6.095385729409376, 2.377133802224657),
(8.522913365698605, 3.2395995841267844),
(8.827829601859406, 3.9298809217233766),
(1.4749644859469302, 8.038753079253127),
(9.005430657826324, 7.58011186920019),
(8.700789540392917, 1.2217577293254112)]
81 10個高斯分布的坐標點random模塊中的gauss(u,sigma)生成均值為u, 標準差為sigma的滿足高斯分布的值,如下生成10個二維坐標點,樣本誤差(y-2*x-1)滿足均值為0,標準差為1的高斯分布:
from random import gauss
x = range(10)
y = [2*xi+1+gauss(0,1) for xi in x]
points = list(zip(x,y))
### 10個二維點:
[(0, -0.86789025305992),
(1, 4.738439437453464),
(2, 5.190278040856102),
(3, 8.05270893133576),
(4, 9.979481700775292),
(5, 11.960781766216384),
(6, 13.025427054303737),
(7, 14.02384035204836),
(8, 15.33755823101161),
(9, 17.565074449028497)]
82 chain高效串聯多個容器對象chain函數串聯a和b,兼顧內存效率同時寫法更加優雅。
from itertools import chain
a = [1,3,5,0]
b = (2,4,6)
for i in chain(a,b):
print(i)
### 結果
1
3
5
0
2
4
6
83 操作函數對象In [31]: def f():
...: print('i\'m f')
...:
In [32]: def g():
...: print('i\'m g')
...:
In [33]: [f,g][1]()
i'm g創建函數對象的list,根據想要調用的index,方便統一調用。
84 生成逆序序列list(range(10,-1,-1)) # [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]第三個參數為負時,表示從第一個參數開始遞減,終止到第二個參數(不包括此邊界)
85 函數的五類參數使用例子python五類參數:位置參數,關鍵字參數,默認參數,可變位置或關鍵字參數的使用。
def f(a,*b,c=10,**d):
print(f'a:{a},b:{b},c:{c},d:{d}')默認參數c不能位於可變關鍵字參數d後.
調用f:
In [10]: f(1,2,5,width=10,height=20)
a:1,b:(2, 5),c:10,d:{'width': 10, 'height': 20}可變位置參數b實參後被解析為元組(2,5);而c取得默認值10; d被解析為字典.
再次調用f:
In [11]: f(a=1,c=12)
a:1,b:(),c:12,d:{}a=1傳入時a就是關鍵字參數,b,d都未傳值,c被傳入12,而非默認值。
注意觀察參數a, 既可以f(1),也可以f(a=1) 其可讀性比第一種更好,建議使用f(a=1)。如果要強制使用f(a=1),需要在前面添加一個星號:
def f(*,a,*b):
print(f'a:{a},b:{b}')此時f(1)調用,將會報錯:TypeError: f() takes 0 positional arguments but 1 was given
只能f(a=1)才能OK.
說明前面的*發揮作用,它變為只能傳入關鍵字參數,那麼如何查看這個參數的類型呢?藉助python的inspect模塊:
In [22]: for name,val in signature(f).parameters.items():
...: print(name,val.kind)
...:
a KEYWORD_ONLY
b VAR_KEYWORD可看到參數a的類型為KEYWORD_ONLY,也就是僅僅為關鍵字參數。
但是,如果f定義為:
def f(a,*b):
print(f'a:{a},b:{b}')查看參數類型:
In [24]: for name,val in signature(f).parameters.items():
...: print(name,val.kind)
...:
a POSITIONAL_OR_KEYWORD
b VAR_POSITIONAL可以看到參數a既可以是位置參數也可是關鍵字參數。
86 使用slice對象生成關於蛋糕的序列cake1:
In [1]: cake1 = list(range(5,0,-1))
In [2]: b = cake1[1:10:2]
In [3]: b
Out[3]: [4, 2]
In [4]: cake1
Out[4]: [5, 4, 3, 2, 1]再生成一個序列:
In [5]: from random import randint
...: cake2 = [randint(1,100) for _ in range(100)]
...: # 同樣以間隔為2切前10個元素,得到切片d
...: d = cake2[1:10:2]
In [6]: d
Out[6]: [75, 33, 63, 93, 15]你看,我們使用同一種切法,分別切開兩個蛋糕cake1,cake2. 後來發現這種切法極為經典,又拿它去切更多的容器對象。
那麼,為什麼不把這種切法封裝為一個對象呢?於是就有了slice對象。
定義slice對象極為簡單,如把上面的切法定義成slice對象:
perfect_cake_slice_way = slice(1,10,2)
#去切cake1
cake1_slice = cake1[perfect_cake_slice_way]
cake2_slice = cake2[perfect_cake_slice_way]
In [11]: cake1_slice
Out[11]: [4, 2]
In [12]: cake2_slice
Out[12]: [75, 33, 63, 93, 15]與上面的結果一致。
對於逆向序列切片,slice對象一樣可行:
a = [1,3,5,7,9,0,3,5,7]
a_ = a[5:1:-1]
named_slice = slice(5,1,-1)
a_slice = a[named_slice]
In [14]: a_
Out[14]: [0, 9, 7, 5]
In [15]: a_slice
Out[15]: [0, 9, 7, 5]頻繁使用同一切片的操作可使用slice對象抽出來,復用的同時還能提高代碼可讀性。
87 lambda 函數的動畫演示有些讀者反映,lambda函數不太會用,問我能不能解釋一下。
比如,下面求這個 lambda函數:
def max_len(*lists):
return max(*lists, key=lambda v: len(v))有兩點疑惑:
lambda函數有返回值嗎?如果有,返回值是多少?調用上面函數,求出以下三個最長的列表:
r = max_len([1, 2, 3], [4, 5, 6, 7], [8])
print(f'更長的列表是{r}')程序完整運行過程,動畫演示如下:
結論:
參數v的可能取值為*lists,也就是 tuple 的一個元素。
lambda函數返回值,等於lambda v冒號後表達式的返回值。
88 粘性之禪7 行代碼夠燒腦,不信試試~~
def product(*args, repeat=1):
pools = [tuple(pool) for pool in args] * repeat
result = [[]]
for pool in pools:
result = [x+[y] for x in result for y in pool]
for prod in result:
yield tuple(prod)調用函數:
rtn = product('xyz', '12', repeat=3)
print(list(rtn))快去手動敲敲,看看輸出啥吧~~
89 元類xiaoming, xiaohong, xiaozhang 都是學生,這類群體叫做 Student.
Python 定義類的常見方法,使用關鍵字 class
In [36]: class Student(object):
...: passxiaoming, xiaohong, xiaozhang 是類的實例,則:
xiaoming = Student()
xiaohong = Student()
xiaozhang = Student()創建後,xiaoming 的 __class__ 屬性,返回的便是 Student類
In [38]: xiaoming.__class__
Out[38]: __main__.Student問題在於,Student 類有 __class__屬性,如果有,返回的又是什麼?
In [39]: xiaoming.__class__.__class__
Out[39]: type哇,程序沒報錯,返回 type
那麼,我們不妨猜測:Student 類,類型就是 type
換句話說,Student類就是一個對象,它的類型就是 type
所以,Python 中一切皆對象,類也是對象
Python 中,將描述 Student 類的類被稱為:元類。
按照此邏輯延伸,描述元類的類被稱為:元元類,開玩笑了~ 描述元類的類也被稱為元類。
聰明的朋友會問了,既然 Student 類可創建實例,那麼 type 類可創建實例嗎?如果能,它創建的實例就叫:類 了。你們真聰明!
說對了,type 類一定能創建實例,比如 Student 類了。
In [40]: Student = type('Student',(),{})
In [41]: Student
Out[41]: __main__.Student它與使用 class 關鍵字創建的 Student 類一模一樣。
Python 的類,因為又是對象,所以和 xiaoming,xiaohong 對象操作相似。支持:
In [43]: StudentMirror = Student # 類直接賦值 # 類直接賦值
In [44]: Student.class_property = 'class_property' # 添加類屬性
In [46]: hasattr(Student, 'class_property')
Out[46]: True元類,確實使用不是那麼多,也許先了解這些,就能應付一些場合。就連 Python 界的領袖 Tim Peters 都說:
「元類就是深度的魔法,99%的用戶應該根本不必為此操心。」
90 對象序列化對象序列化,是指將內存中的對象轉化為可存儲或傳輸的過程。很多場景,直接一個類對象,傳輸不方便。
但是,當對象序列化後,就會更加方便,因為約定俗成的,接口間的調用或者發起的 web 請求,一般使用 json 串傳輸。
實際使用中,一般對類對象序列化。先創建一個 Student 類型,並創建兩個實例。
class Student():
def __init__(self,**args):
self.ids = args['ids']
self.name = args['name']
self.address = args['address']
xiaoming = Student(ids = 1,name = 'xiaoming',address = '北京')
xiaohong = Student(ids = 2,name = 'xiaohong',address = '南京')導入 json 模塊,調用 dump 方法,就會將列表對象 [xiaoming,xiaohong],序列化到文件 json.txt 中。
import json
with open('json.txt', 'w') as f:
json.dump([xiaoming,xiaohong], f, default=lambda obj: obj.__dict__, ensure_ascii=False, indent=2, sort_keys=True)生成的文件內容,如下:
[
{
"address": "北京",
"ids": 1,
"name": "xiaoming"
},
{
"address": "南京",
"ids": 2,
"name": "xiaohong"
}
]
資源下載所有300多個例子已經整合成182頁的pdf,可以到作者倉庫找到下載方式:
https://github.com/jackzhenguo/python-small-examples