日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

Pythonic---------详细讲解

發布時間:2023/11/30 python 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Pythonic---------详细讲解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
作者:半載流殤 鏈接:https://zhuanlan.zhihu.com/p/35219750 來源:知乎 著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。Pythonic,簡言之就是以Python這門語言獨特的方式寫出既簡潔又優美的代碼!筆者精心整理了許多實用的Python tricks,想要提高效率、寫出高質量的Python代碼的話此文必看。 注:請將Python更新到3.6版,方能完美運行本文的所有代碼。字符串格式化字符串在字符串前加f,就可以在里面用大括號嵌入變量了(可以代替format函數)>>> a = 5 >>> b = 10 >>> f'Five plus ten is {a + b} and not {2 * (a + b)}.' 'Five plus ten is 15 and not 30.' 字符串拼接>>> text = ['I', ' Love ', 'Python!'] >>> print(''.join(text)) I Love Python! 字符串的contains>>> 'ov' in 'love' True 反轉元素>>> 'Love'[::-1] 'evoL' >>> for e in reversed([1,3,5]): print(e) 5 3 1 去除非法字符串保存文件時,我們必須去除一些非法字符串,此處利用any函數實現def rectify(name):if any(symbol in name for symbol in ['?', '<', '>', '|', '*', '"', ":"]):name = ''.join([c for c in name if c not in ['?', '<', '>', '|', '*', '"', ":"]])return name HTML轉義>>> import html >>> html.unescape('&lt') '<' >>> html.escape('<') '&lt;' 函數可變參數*args:任意數量的位置參數,可被打包成元組。**kwargs:任意數量的關鍵詞參數,可被打包成字典。打包def foo(*args, **kwargs):print(f"args: {args}")print(f"kwargs: {kwargs}")>>> foo(1,2,3,4, a=1,b=2,c=3) args: (1, 2, 3, 4) kwargs: {'a': 1, 'b': 2, 'c': 3} 解包def foo(x, y):print(x, y)alist = [1, 2] adict = {'x': 1, 'y': 2}>>> foo(*alist) 1, 2 >>> foo(**adict) 1, 2 裝飾器裝飾器的主要用途:打印日志、檢測性能、數據庫事務、URL路由它本質上就是一個高階函數,它接收一個函數作為參數,然后,返回一個新函數。想理解裝飾器,就得知道以下兩點:1. 函數皆對象2. 閉包特性(內函數能捕捉到外函數的環境變量)簡單的日志函數from datetime import datetime import functools def log(f):@functools.wraps(f)def wr(*args, **kwargs):print(f'call {f.__name__}() at {datetime.now()}')return f(*args, **kwargs)return wr@log def square(x):return x ** 2>>> square(2) call square() at 2018-01-24 11:01:19.547516 4 注意到為了讓@deco自適應任何參數定義的函數,我們將可變參數args, *kwargs作為了wr的參數@functools.wraps(f)為了防止wr的函數屬性覆蓋掉原函數的屬性,我們必須利用@functools.wraps(f)來把原函數的所有屬性復制到新函數里# 不加@functools.wraps(f)的情況下 >>> square.__name__ 'wr' # 加了@functools.wraps(f)的情況下 >>> square.__name__ 'square' 如果想給裝飾器傳遞參數,那么你必須利用閉包特性再嵌套一層函數,不過這并不常用。函數性能檢測def perf(f):@functools.wraps(f)def wr(*args, **kwargs):start = time.time()r = f(*args, **kwargs)end = time.time()print(f'call {f.__name__}() in {end - start}')return rreturn wr@perf def test(x):time.sleep(2)return x>>> test(5) call test() in 2.0007083415985107 5 數據庫的cursordef link_mysql(fun):def wr(*args, **kwargs):with pymysql.connect(host=host, port=port, user=user, passwd=passwd, db=dbname, charset=charset) as cur:fun(cur, *args, **kwargs)return wr@link_mysql def insert_data(cur, ...):# execute your sql here. 上下文管理器應用文件操作(超常用)、進程互斥鎖和支持上下文的其他對象目的是為了代替try語句和簡化語法以文件操作為例:利用它,文件會自動打開和關閉with open('/path/to/file', 'r') as f:handle_f 上下文語句支持嵌套(nested)例如將a文件的源數據寫入b文件里:with open('a.txt') as i, open('b.txt') as o:o.write(i.read()) 實質通過上下文管理協議__enter__和__exit__來實現Python有個庫contextlib利用生成器簡化了這種實現,以下是大體框架from contextlib import contextmanager@contextmanager def make_context() :# entertry:yield <value>except Exception as e:# handle_errfinally:# exit with make_context() as <value>:# handle_value 以下是with語句操作文件的實質由于自定義,函數名用my_open,但功能和open幾乎一樣@contextmanager def my_open(filename, mode):f = open(filename, mode)try:yield fexcept Exception as e:raise efinally:f.close()with my_open('/path/to/file', 'r') as f:handle_f 偏函數partial()用于把一個函數的某些參數給固定住(也就是設置默認值),并返回一個新的函數。def int2(x, base=2):return int(x, base) 相當于:import functools int2 = functools.partial(int, base=2) 數據結構元組元組是一個immutable對象,有以下重要性:- 性能優化- 線程安全- 可以作為dict的key(hashable)- 拆包特性元組拆包a, b = b, a兩個數字交換的原理就是它。以下是利用它來獲取文件名及其擴展名>>> import os >>> filename, ext = os.path.splitext('patch.exe') >>> filename 'patch' >>> ext 'exe' 更多的解包方式(_代表舍棄,*代表可變長元組)>>> t = (1, 2, 3, 4) >>> first, *middle, last = t >>> middle [2, 3] >>> _, *rest = t >>> rest [2, 3, 4] 列表切片如果想要獲取列表的多個元素,就得用到切片list[start:stop:step] 你甚至可以給切片命名,增強復用性和可讀性:s = slice(start,stop,step) list[s] 切片的原理是序列協議class Seq:def __getitem__(self, index):return index>>> s = Seq() >>> s[1:5:2] slice(1, 5, 2) 以上實現的是不可變序列協議,如果可變的話還要添加__setitem__()如果在運行時添加協議的話也行,這叫猴子補丁>>> def set_item(self, key, value):self[key] = value >>> classname.__setitem__ = set_item 列表推導式這是Python最強大的幾個特征之一。格式也很簡單,其中if條件可以省略,for循環可以有多個[i for i in iterable if condition] 10-20所有偶數的平方:[i*i for i in range(10, 21) if i % 2 == 0 ] 一行實現快排def qsort(arr):return arr if len(arr) <= 1 else qsort([x for x in arr[1:] if x<arr[0]]) + [arr[0]] + qsort([x for x in arr[1:] if x>=arr[0]]) 索引迭代enumerate()可以把一個list變成索引-元素對。for i, value in enumerate(['A', 'B', 'C']):print(i, value) 0 A 1 B 2 C zipzip()可以將可迭代的對象作為參數,將對象中對應的元素打包成一個個元組,并返回一個迭代器,常用于同時遍歷兩個可迭代對象。>>> li1 = ['Python' ,'JavaScript', 'Java'] >>> li2 = [1, 2, 3] >>> nl = zip(li1, li2) <zip object at memory> >>> list(nl) [('Python', 1), ('JavaScript', 2), ('Java', 3)] 配合dict可以生成字典>>> l1 = ['A', 'B', 'C'] >>> l2 = [1, 2, 3] >>> dict(zip(l1, l2)) {'A': 1, 'B': 2, 'C': 3} append和extend>>> x = [1, 2, 3] >>> x.extend([4, 5]) >>> x [1, 2, 3, 4, 5] >>> x.append([6, 7]) >>> x [1, 2, 3, 4, 5, [6, 7]] 集合運算首先將要比較的兩個list轉換為set,再轉回list就行了>>> l1 = [1, 2, 3, 4] >>> l2 = [2, 3, 5, 7] >>> list(set(l1) & set(l2)) [2, 3] >>> list(set(l1) | set(l2)) [1, 2, 3, 4, 5, 7] >>> list(set(l1) ^ set(l2)) [1, 4, 5, 7] 字典本質是鍵值對哈希表get用來獲取某個鍵的值,不存在的話就用設置的default(默認為None)>>> d = dict(a=1, b=2) >>> d.get('a') 1 >>> d.get('c') >>> d.get('d', 2) 2 合并>>> d1 = {'a':1, 'b':2} >>> d2 = {'c':3, 'd':4} >>> nd = {**d1, **d2} >>> nd {'a': 1, 'b': 2, 'c': 3, 'd': 4} 類似的,列表也可以這樣合并>>> l1 = [1, 2] >>> l2 = [3, 4] >>> l3 = [*l1, *l2] >>> l3 [1, 2, 3, 4] 鍵值對反轉>>> kv = {'a': 1, 'b':2 , 'c': 3} >>> vk = zip(kv.values(), kv.keys()) >>> dict(vk) {1: 'a', 2: 'b', 3: 'c'} >>> min(vk) (1, 'a') >>> sorted(vk) [(1, 'a'), (2, 'b'), (3, 'c')] 鍵值排序>>> rows = [{k1: v1, k2: v2 ...}, ...] >>> from operator import itemgetter # 根據k1排序 >>> sorted(rows, key=itemgetter(k1)) # 類似的,對于class的對象可以用attrgetter進行排序 集合運算>>> a = {'a': 1, 'b': 2, 'c': 3} >>> b = {'x': 1, 'b': 2, 'c': 4} >>> a.keys() & b.keys() {'b', 'c'} >>> a.keys() - b.keys() {'a'} >>> a.items() & b.items() {('b', 2)} 其他數據結構具名元組常用于構建簡單的類>>> from collections import namedtuple >>> Point = namedtuple('Point', ['x', 'y']) >>> p = Point(x=11, y=22) >>> p Point(x=11, y=22) >>> p.x + p.y 33 >>> coord = (33, 44) >>> q = Point(*coord) >>> q Point(x=33, y=44) 默認值字典常用于統計數目>>> from collections import defaultdict >>> words = ('python', 'java', 'ruby', 'python', 'C', 'java', 'C++', 'C') >>> counts = defaultdict(int) >>> for word in words: ... counts[word] += 1 >>> counts defaultdict(<class 'int'>, {'python': 2, 'java': 2, 'ruby': 1, 'C': 2, 'C++': 1}) 雙向隊列>>> from collections import deque >>> q = deque(["Eric", "John", "Michael"]) >>> q.append("Terry") >>> q deque(['Eric', 'John', 'Michael', 'Terry']) >>> q.popleft() Eric' >>> q.pop() 'Terry' >>> q deque(['John', 'Michael']) 計數器>>> from collections import Counter >>> c = Counter('hello world') >>> c Counter({'l': 3, 'o': 2, ' ': 1, 'e': 1, 'd': 1, 'h': 1, 'r': 1, 'w': 1}) >>> c.most_common(2) [('l', 3), ('o', 2)] 堆>>> import heapq >>> a = [1, 2, 3] >>> b = [4, 5, 6] >>> c = list(heapq.merge(a, b)) >>> c [1, 2, 3, 4, 5, 6] >>> heapq.nlargest(3, c) [6, 5, 4] >>> heapq.nsmallest(3, c) [1, 2, 3] OOP只讀屬性可以通過在變量名前加__來使其變成私有變量,外部無法直接訪問,但可以通過類定義的方法來訪問。class Person(object):def __init__(self, name):self.__name = namedef get_name(self):return self.__namedef set_name(self, name):self.__name = name>>> p = Person('alphardex') >>> p.name Traceback (most recent call last):File "<stdin>", line 1, in <module> AttributeError: 'Person' object has no attribute 'name' >>> p.get_name() 'alphardex' >>> p.set_name('wang') >>> p.get_name() 'wang' @property肯定有的人不習慣通過方法來訪問私有變量,那么如何用屬性來訪問私有變量呢?這時就要用到@property了,它可以把一個方法變成屬性調用class Person(object):def __init__(self, name):self.__name = name@propertydef name(self):return self.__name@name.setterdef name(self, value):self.__name = value>>> p = Person('alphardex') >>> p.name 'alphardex' >>> p.name = 'wang' >>> p.name 'wang' slots當我們定義了一個class并用其創建了一個實例后,可以動態地給其綁定屬性,如果要限制這一點,可以利用__slots__class Person(object):__slots__ = ('name', 'age')>>> p = Person('wang') >>> p.name = 'wang' >>> p.age = 21 >>> p.skill = 'Python' Traceback (most recent call last):File "<stdin>", line 1, in <module> AttributeError: 'Person' object has no attribute 'skill' 魔術方法魔術方法可以用來定制類的功能。比如__repr__用來調試時打印類的字符串class Person(object):def __init__(self, name, age):self.name = nameself.age = agedef __repr__(self):return f'<Person {self.name} age: {self.age}>'>>> p = Person('alphardex', 21) >>> p <Person alphardex age: 21> 想了解更多魔術方法請參見官方文檔元類type俗話說道生一,一生二,二生三,三生萬物。在Python里可以這么說:type生元類,元類生類,類生實例。用一個數字變量的創建來說明這一點吧>>> age = 21 >>> age.__class__ <class 'int'> >>> age.__class__.__class__ <class 'type'> age可以看作為int類的實例,而int類又可以看做type類的實例。也就是說,type創建了int類,實際上諸如str和bool等類也是由type創建的。>>> help(type) Help on class type in module builtins:class type(object)| type(object_or_name, bases, dict)| type(object) -> the object's type| type(name, bases, dict) -> a new typedef say_hello(self, name='world'):print(f'Hello, {name}')>>> Hello = type('Hello', (object,), dict(hello=say_hello)) >>> h = Hello() >>> type(Hello) <class 'type'> >>> type(h) <class '__main__.Hello'> 通過用help查看type,可以發現它確實能動態地創建類:第一個參數是類名name,第二個參數是基類bases,第三個參數是dict,里面包含著類的所有方法。實際上,type是Python的一個內置元類。自定義元類當然,你也可以利用type來定義自己的元類。class JSArrayMeta(type):def __new__(cls, name, bases, attrs):attrs['push'] = lambda self, value: self.append(value)attrs['shift'] = lambda self: self.pop(0)attrs['includes'] = lambda self, value: value in selfreturn type.__new__(cls, name, bases, attrs)class JSList(list, metaclass=JSArrayMeta):def __init__(self, value):self.extend(value)>>> l = JSList([1, 2, 3]) >>> l [1, 2, 3] >>> l.push('a') >>> l [1, 2, 3, 'a'] >>> l.shift() 1 >>> l [2, 3, 'a'] >>> l.includes(3) True 我們首先定制了一個元類,叫JSArrayMetaclass(沒錯就是JS里的數組XD)注意元類的命名規則:結尾一定要有Meta作為識別__new__方法用來創建JSList類,它接受4個參數JSList繼承了list類,同時獲得了元類的所有方法其他加載內置模塊利用-m參數,我們可以直接加載Python的模塊# 搭建http服務器 $ python -m http.server # 創建虛擬環境 $ python -m venv <name> # 性能測試 $ python -m cProfile <file.py> # 查看JSON $ cat <file.json> | python -m json.tool 數據序列化import pickle data = ... # Some Python object # 存儲 with open(f'{file}.pickle', 'wb') as f:pickle.dump(data, f) # 讀取 with open(f'{file}.pickle', 'rb') as f:data = pickle.load(f) 數據分析利用pandas模塊可以對數據進行分析$ pip install pandas >>> import pandas as pd >>> data = pd.read_csv(...) # 數據查看 >>> data.columns # 查看數據結構 >>> data.describe() # 簡要數據分析 >>> data.sort_values(by=...) # 對數據排序 # 數據選取 >>> data.head() # 查看前五條數據 >>> data.iloc[n] # 選擇位置為n的數據,支持切片 >>> data[data.A > 0] # 選擇A欄大于0的數據 >>> data[data.B.isin([...])] # 利用in過濾數據 >>> data[~data.B.isin([...])] # 上一句的取反,相當于not in # 缺失值處理 >>> pd.isna(data) # 獲取缺失值的布爾標記 >>> data.dropna(how='any') # 去除所有含有缺失值的欄 >>> data.fillna(value=5) # 填充所有含有缺失值的欄 # 數據保存(可以相互轉換格式,支持excel、csv和json) >>> data.to_json(...)

?

作者:半載流殤
鏈接:https://zhuanlan.zhihu.com/p/35219750
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

Pythonic,簡言之就是以Python這門語言獨特的方式寫出既簡潔又優美的代碼!筆者精心整理了許多實用的Python tricks,想要提高效率、寫出高質量的Python代碼的話此文必看。

注:請將Python更新到3.6版,方能完美運行本文的所有代碼。

字符串

格式化字符串

在字符串前加f,就可以在里面用大括號嵌入變量了(可以代替format函數)

>>> a = 5 >>> b = 10 >>> f'Five plus ten is {a + b} and not {2 * (a + b)}.' 'Five plus ten is 15 and not 30.'

字符串拼接

>>> text = ['I', ' Love ', 'Python!'] >>> print(''.join(text)) I Love Python!

字符串的contains

>>> 'ov' in 'love' True

反轉元素

>>> 'Love'[::-1] 'evoL' >>> for e in reversed([1,3,5]): print(e) 5 3 1

去除非法字符串

保存文件時,我們必須去除一些非法字符串,此處利用any函數實現

def rectify(name):if any(symbol in name for symbol in ['?', '<', '>', '|', '*', '"', ":"]):name = ''.join([c for c in name if c not in ['?', '<', '>', '|', '*', '"', ":"]])return name

HTML轉義

>>> import html >>> html.unescape('&lt') '<' >>> html.escape('<') '&lt;'

函數

可變參數

*args:任意數量的位置參數,可被打包成元組。
**kwargs:任意數量的關鍵詞參數,可被打包成字典。

打包

def foo(*args, **kwargs):print(f"args: {args}")print(f"kwargs: {kwargs}")>>> foo(1,2,3,4, a=1,b=2,c=3) args: (1, 2, 3, 4) kwargs: {'a': 1, 'b': 2, 'c': 3}

解包

def foo(x, y):print(x, y)alist = [1, 2] adict = {'x': 1, 'y': 2}>>> foo(*alist) 1, 2 >>> foo(**adict) 1, 2

裝飾器

裝飾器的主要用途:打印日志、檢測性能、數據庫事務、URL路由
它本質上就是一個高階函數,它接收一個函數作為參數,然后,返回一個新函數。
想理解裝飾器,就得知道以下兩點:
1. 函數皆對象
2. 閉包特性(內函數能捕捉到外函數的環境變量)

簡單的日志函數

from datetime import datetime import functools def log(f):@functools.wraps(f)def wr(*args, **kwargs):print(f'call {f.__name__}() at {datetime.now()}')return f(*args, **kwargs)return wr@log def square(x):return x ** 2>>> square(2) call square() at 2018-01-24 11:01:19.547516 4

注意到為了讓@deco自適應任何參數定義的函數,我們將可變參數args, *kwargs作為了wr的參數

@functools.wraps(f)

為了防止wr的函數屬性覆蓋掉原函數的屬性,我們必須利用@functools.wraps(f)來把原函數的所有屬性復制到新函數里

# 不加@functools.wraps(f)的情況下 >>> square.__name__ 'wr' # 加了@functools.wraps(f)的情況下 >>> square.__name__ 'square'

如果想給裝飾器傳遞參數,那么你必須利用閉包特性再嵌套一層函數,不過這并不常用。

函數性能檢測

def perf(f):@functools.wraps(f)def wr(*args, **kwargs):start = time.time()r = f(*args, **kwargs)end = time.time()print(f'call {f.__name__}() in {end - start}')return rreturn wr@perf def test(x):time.sleep(2)return x>>> test(5) call test() in 2.0007083415985107 5

數據庫的cursor

def link_mysql(fun):def wr(*args, **kwargs):with pymysql.connect(host=host, port=port, user=user, passwd=passwd, db=dbname, charset=charset) as cur:fun(cur, *args, **kwargs)return wr@link_mysql def insert_data(cur, ...):# execute your sql here.

上下文管理器

應用

文件操作(超常用)、進程互斥鎖和支持上下文的其他對象
目的是為了代替try語句和簡化語法
以文件操作為例:利用它,文件會自動打開和關閉

with open('/path/to/file', 'r') as f:handle_f

上下文語句支持嵌套(nested)
例如將a文件的源數據寫入b文件里:

with open('a.txt') as i, open('b.txt') as o:o.write(i.read())

實質

通過上下文管理協議__enter__和__exit__來實現
Python有個庫contextlib利用生成器簡化了這種實現,以下是大體框架

from contextlib import contextmanager@contextmanager def make_context() :# entertry:yield <value>except Exception as e:# handle_errfinally:# exitwith make_context() as <value>:# handle_value

以下是with語句操作文件的實質
由于自定義,函數名用my_open,但功能和open幾乎一樣

@contextmanager def my_open(filename, mode):f = open(filename, mode)try:yield fexcept Exception as e:raise efinally:f.close()with my_open('/path/to/file', 'r') as f:handle_f

偏函數

partial()用于把一個函數的某些參數給固定住(也就是設置默認值),并返回一個新的函數。

def int2(x, base=2):return int(x, base)

相當于:

import functools int2 = functools.partial(int, base=2)

數據結構

元組

元組是一個immutable對象,有以下重要性:
- 性能優化
- 線程安全
- 可以作為dict的key(hashable)
- 拆包特性

元組拆包

a, b = b, a
兩個數字交換的原理就是它。
以下是利用它來獲取文件名及其擴展名

>>> import os >>> filename, ext = os.path.splitext('patch.exe') >>> filename 'patch' >>> ext 'exe'

更多的解包方式(_代表舍棄,*代表可變長元組)

>>> t = (1, 2, 3, 4) >>> first, *middle, last = t >>> middle [2, 3] >>> _, *rest = t >>> rest [2, 3, 4]

列表

切片

如果想要獲取列表的多個元素,就得用到切片

list[start:stop:step]

你甚至可以給切片命名,增強復用性和可讀性:

s = slice(start,stop,step) list[s]

切片的原理是序列協議

class Seq:def __getitem__(self, index):return index>>> s = Seq() >>> s[1:5:2] slice(1, 5, 2)

以上實現的是不可變序列協議,如果可變的話還要添加__setitem__()
如果在運行時添加協議的話也行,這叫猴子補丁

>>> def set_item(self, key, value):self[key] = value >>> classname.__setitem__ = set_item

列表推導式

這是Python最強大的幾個特征之一。
格式也很簡單,其中if條件可以省略,for循環可以有多個

[i for i in iterable if condition]

10-20所有偶數的平方:

[i*i for i in range(10, 21) if i % 2 == 0 ]

一行實現快排

def qsort(arr):return arr if len(arr) <= 1 else qsort([x for x in arr[1:] if x<arr[0]]) + [arr[0]] + qsort([x for x in arr[1:] if x>=arr[0]])

索引迭代

enumerate()可以把一個list變成索引-元素對。

for i, value in enumerate(['A', 'B', 'C']):print(i, value) 0 A 1 B 2 C

zip

zip()可以將可迭代的對象作為參數,將對象中對應的元素打包成一個個元組,并返回一個迭代器,常用于同時遍歷兩個可迭代對象。

>>> li1 = ['Python' ,'JavaScript', 'Java'] >>> li2 = [1, 2, 3] >>> nl = zip(li1, li2) <zip object at memory> >>> list(nl) [('Python', 1), ('JavaScript', 2), ('Java', 3)]

配合dict可以生成字典

>>> l1 = ['A', 'B', 'C'] >>> l2 = [1, 2, 3] >>> dict(zip(l1, l2)) {'A': 1, 'B': 2, 'C': 3}

append和extend

>>> x = [1, 2, 3] >>> x.extend([4, 5]) >>> x [1, 2, 3, 4, 5] >>> x.append([6, 7]) >>> x [1, 2, 3, 4, 5, [6, 7]]

集合運算

首先將要比較的兩個list轉換為set,再轉回list就行了

>>> l1 = [1, 2, 3, 4] >>> l2 = [2, 3, 5, 7] >>> list(set(l1) & set(l2)) [2, 3] >>> list(set(l1) | set(l2)) [1, 2, 3, 4, 5, 7] >>> list(set(l1) ^ set(l2)) [1, 4, 5, 7]

字典

本質是鍵值對哈希表

get

用來獲取某個鍵的值,不存在的話就用設置的default(默認為None)

>>> d = dict(a=1, b=2) >>> d.get('a') 1 >>> d.get('c') >>> d.get('d', 2) 2

合并

>>> d1 = {'a':1, 'b':2} >>> d2 = {'c':3, 'd':4} >>> nd = {**d1, **d2} >>> nd {'a': 1, 'b': 2, 'c': 3, 'd': 4}

類似的,列表也可以這樣合并

>>> l1 = [1, 2] >>> l2 = [3, 4] >>> l3 = [*l1, *l2] >>> l3 [1, 2, 3, 4]

鍵值對反轉

>>> kv = {'a': 1, 'b':2 , 'c': 3} >>> vk = zip(kv.values(), kv.keys()) >>> dict(vk) {1: 'a', 2: 'b', 3: 'c'} >>> min(vk) (1, 'a') >>> sorted(vk) [(1, 'a'), (2, 'b'), (3, 'c')]

鍵值排序

>>> rows = [{k1: v1, k2: v2 ...}, ...] >>> from operator import itemgetter # 根據k1排序 >>> sorted(rows, key=itemgetter(k1)) # 類似的,對于class的對象可以用attrgetter進行排序

集合運算

>>> a = {'a': 1, 'b': 2, 'c': 3} >>> b = {'x': 1, 'b': 2, 'c': 4} >>> a.keys() & b.keys() {'b', 'c'} >>> a.keys() - b.keys() {'a'} >>> a.items() & b.items() {('b', 2)}

其他數據結構

具名元組

常用于構建簡單的類

>>> from collections import namedtuple >>> Point = namedtuple('Point', ['x', 'y']) >>> p = Point(x=11, y=22) >>> p Point(x=11, y=22) >>> p.x + p.y 33 >>> coord = (33, 44) >>> q = Point(*coord) >>> q Point(x=33, y=44)

默認值字典

常用于統計數目

>>> from collections import defaultdict >>> words = ('python', 'java', 'ruby', 'python', 'C', 'java', 'C++', 'C') >>> counts = defaultdict(int) >>> for word in words: ... counts[word] += 1 >>> counts defaultdict(<class 'int'>, {'python': 2, 'java': 2, 'ruby': 1, 'C': 2, 'C++': 1})

雙向隊列

>>> from collections import deque >>> q = deque(["Eric", "John", "Michael"]) >>> q.append("Terry") >>> q deque(['Eric', 'John', 'Michael', 'Terry']) >>> q.popleft() Eric' >>> q.pop() 'Terry' >>> q deque(['John', 'Michael'])

計數器

>>> from collections import Counter >>> c = Counter('hello world') >>> c Counter({'l': 3, 'o': 2, ' ': 1, 'e': 1, 'd': 1, 'h': 1, 'r': 1, 'w': 1}) >>> c.most_common(2) [('l', 3), ('o', 2)]

>>> import heapq >>> a = [1, 2, 3] >>> b = [4, 5, 6] >>> c = list(heapq.merge(a, b)) >>> c [1, 2, 3, 4, 5, 6] >>> heapq.nlargest(3, c) [6, 5, 4] >>> heapq.nsmallest(3, c) [1, 2, 3]

OOP

只讀屬性

可以通過在變量名前加__來使其變成私有變量,外部無法直接訪問,但可以通過類定義的方法來訪問。

class Person(object):def __init__(self, name):self.__name = namedef get_name(self):return self.__namedef set_name(self, name):self.__name = name>>> p = Person('alphardex') >>> p.name Traceback (most recent call last):File "<stdin>", line 1, in <module> AttributeError: 'Person' object has no attribute 'name' >>> p.get_name() 'alphardex' >>> p.set_name('wang') >>> p.get_name() 'wang'

@property

肯定有的人不習慣通過方法來訪問私有變量,那么如何用屬性來訪問私有變量呢?這時就要用到@property了,它可以把一個方法變成屬性調用

class Person(object):def __init__(self, name):self.__name = name@propertydef name(self):return self.__name@name.setterdef name(self, value):self.__name = value>>> p = Person('alphardex') >>> p.name 'alphardex' >>> p.name = 'wang' >>> p.name 'wang'

slots

當我們定義了一個class并用其創建了一個實例后,可以動態地給其綁定屬性,如果要限制這一點,可以利用__slots__

class Person(object):__slots__ = ('name', 'age')>>> p = Person('wang') >>> p.name = 'wang' >>> p.age = 21 >>> p.skill = 'Python' Traceback (most recent call last):File "<stdin>", line 1, in <module> AttributeError: 'Person' object has no attribute 'skill'

魔術方法

魔術方法可以用來定制類的功能。
比如__repr__用來調試時打印類的字符串

class Person(object):def __init__(self, name, age):self.name = nameself.age = agedef __repr__(self):return f'<Person {self.name} age: {self.age}>'>>> p = Person('alphardex', 21) >>> p <Person alphardex age: 21>

想了解更多魔術方法請參見官方文檔

元類

type

俗話說道生一,一生二,二生三,三生萬物。
在Python里可以這么說:type生元類,元類生類,類生實例。
用一個數字變量的創建來說明這一點吧

>>> age = 21 >>> age.__class__ <class 'int'> >>> age.__class__.__class__ <class 'type'>

age可以看作為int類的實例,而int類又可以看做type類的實例。
也就是說,type創建了int類,實際上諸如str和bool等類也是由type創建的。

>>> help(type) Help on class type in module builtins:class type(object)| type(object_or_name, bases, dict)| type(object) -> the object's type| type(name, bases, dict) -> a new typedef say_hello(self, name='world'):print(f'Hello, {name}')>>> Hello = type('Hello', (object,), dict(hello=say_hello)) >>> h = Hello() >>> type(Hello) <class 'type'> >>> type(h) <class '__main__.Hello'>

通過用help查看type,可以發現它確實能動態地創建類:第一個參數是類名name,第二個參數是基類bases,第三個參數是dict,里面包含著類的所有方法。
實際上,type是Python的一個內置元類。

自定義元類

當然,你也可以利用type來定義自己的元類。

class JSArrayMeta(type):def __new__(cls, name, bases, attrs):attrs['push'] = lambda self, value: self.append(value)attrs['shift'] = lambda self: self.pop(0)attrs['includes'] = lambda self, value: value in selfreturn type.__new__(cls, name, bases, attrs)class JSList(list, metaclass=JSArrayMeta):def __init__(self, value):self.extend(value)>>> l = JSList([1, 2, 3]) >>> l [1, 2, 3] >>> l.push('a') >>> l [1, 2, 3, 'a'] >>> l.shift() 1 >>> l [2, 3, 'a'] >>> l.includes(3) True

?

  • 我們首先定制了一個元類,叫JSArrayMetaclass(沒錯就是JS里的數組XD)
  • 注意元類的命名規則:結尾一定要有Meta作為識別
  • __new__方法用來創建JSList類,它接受4個參數
  • JSList繼承了list類,同時獲得了元類的所有方法

其他

加載內置模塊

利用-m參數,我們可以直接加載Python的模塊

# 搭建http服務器 $ python -m http.server # 創建虛擬環境 $ python -m venv <name> # 性能測試 $ python -m cProfile <file.py> # 查看JSON $ cat <file.json> | python -m json.tool

數據序列化

import pickle data = ... # Some Python object # 存儲 with open(f'{file}.pickle', 'wb') as f:pickle.dump(data, f) # 讀取 with open(f'{file}.pickle', 'rb') as f:data = pickle.load(f)

數據分析

利用pandas模塊可以對數據進行分析

$ pip install pandas >>> import pandas as pd >>> data = pd.read_csv(...) # 數據查看 >>> data.columns # 查看數據結構 >>> data.describe() # 簡要數據分析 >>> data.sort_values(by=...) # 對數據排序 # 數據選取 >>> data.head() # 查看前五條數據 >>> data.iloc[n] # 選擇位置為n的數據,支持切片 >>> data[data.A > 0] # 選擇A欄大于0的數據 >>> data[data.B.isin([...])] # 利用in過濾數據 >>> data[~data.B.isin([...])] # 上一句的取反,相當于not in # 缺失值處理 >>> pd.isna(data) # 獲取缺失值的布爾標記 >>> data.dropna(how='any') # 去除所有含有缺失值的欄 >>> data.fillna(value=5) # 填充所有含有缺失值的欄 # 數據保存(可以相互轉換格式,支持excel、csv和json) >>> data.to_json(...)

轉載于:https://www.cnblogs.com/yezefei/p/8709039.html

總結

以上是生活随笔為你收集整理的Pythonic---------详细讲解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。