清華教授花一個月把Python所有基本用法歸納好了!末有驚喜

廢話不多寫,直接開始內容。

一、內置函數

1. complex([real[,imag]])

返回一個複數,實部 + 虛部*1j,或者把字符串或者數字轉成複數形式。

參數可以是複數表達式,也可以是字符串。當參數是字符串的時候,數字與操作符之間不能有空格。即comple('1 + 2j')是錯誤的。

print(complex(1, 2))print(complex(1 + 2j))print(complex('1+2j'))# 輸出 1+2jprint(complex(1))# 輸出 1+0j

滿足:實部 + 虛部*1j 的數被稱爲複數。

a = 1 + 3j# 求實部print(a.real)# 求虛部print(a.imag)# 求共軛print(a.conjugate())

2. chr(i) 與 ord(i)

chr(i) 是將當前整數 i 轉成對應的 ascii 字符,可以是十進制,也可以是十六進制,其中0 <= i <= 0x10ffff (1114111)。其對應的逆操作爲 ord(i),i 爲 ascii 字符。

下面的函數演示如何求一個可迭代對象的 ascil字符 或者其對應的數值。注意函數 ordplus ,參數 x 中的每一個元素必須是單個字符,如果是列表,形式如下:[‘P’ , ‘y’, ‘t’ , ‘h’, ‘o’ , ‘n’]。

def chrplus(x): chr_string = '' for elem in x: chr_string += chr(elem) return chr_stringdef ordplus(x): ord_list = [] for elem in x: ord_list.append(ord(elem))return ord_listx = 'Python高效編程'temp = ordplus(x)print(temp)# 輸出:[112, 121, 116, 104, 111, 110,# 39640, 25928, 32534,31243]init = chrplus(temp)print(init)# 輸出:Python高效編程

3.enumerate(iterable, start=0)

返回 enumerate 對象。迭代對象必須是序列,迭代器,或者其他支持迭代的對象。enmerate() 函數返回的是迭代器,同樣是可迭代對象。每次迭代的元素,都包含元素在序列裏的序號(strat 默認值爲 0) 和元素對應值。因此,我們可以用 for 循環獲取返回值。

等價於:

def enumerate(sequence, start=0): n = start for elem in sequence: yield n, elem n += 1for i, elem in enumerate(['P', 'y', 't', 'h', 'o', 'n']): print(i, elem)

4. abs(x)

返回數的絕對值。參數可以是整數或者浮點數。如果參數是複數,返回複數的模。Python 中虛數用數值加上字符 j 的形式表示。要注意 j 前面的數值不能省略,比如 1j。進裙:528397617免費領取視頻資料

下面是我寫的簡易版的 abs 函數:

from math import sqrtdef naive_abs(x): # isinstance 判斷參數x是否爲整數或浮點數 if isinstance(x, int) or isinstance(x, float): if x < 0: x = - x # 判斷參數x是否爲複數 elif isinstance(x, complex): # x.real 複數的實部 # x.imag 複數的虛部 real = x.real imag = x.imag # 求複數的模 x = sqrt(real ** 2 + imag ** 2) else : return '請輸入 int float complex' return xprint(abs(3+4j))print(naive_abs(3+4j))# 輸出 5.0print(abs(-6))print(naive_abs(-6))# 輸出 6

清華教授花一個月把Python所有基本用法歸納好了!末有驚喜

 

 

二、算法與數據結構

1. 二分查找

要想使用二分搜索,首先要確保迭代序列是有序的。對於無序序列,我們首先要進行排序操作。

每次循環縮小一半搜索範圍,時間複雜度爲 O(logn)。每次循環,比較選取的中間數與需要查找的數字,如果待查數小於中間數,就減少右界至中間數的前一個數;如果待查數大於中間數,就增加左界到中間數後一個數;如果待查數等於中間數,返回中間數的下標,該下標即爲待查數在序列中的位置。當左界大於右界時,循環結束,說明序列中並沒有待查數。

def binary_search(item, find): # 有序可迭代對象 left, right = 0, len(item) - 1 mid = left + (right - left) // 2 while left <= right: if item[mid] == find: return mid elif item[mid] > find: right = mid - 1 else: left = mid + 1 mid = left + (right - left) // 2return Noneseq = [1, 4, 7, 9, 13, 17, 18, 21, 34, 45, 65]binary_search(seq, 13)# 輸出:4

2. 快速排序

首先要打亂序列順序 ,以防算法陷入最壞時間複雜度。快速排序使用“分而治之”的方法。對於一串序列,首先從中選取一個數,凡是小於這個數的值就被放在左邊一摞,凡是大於這個數的值就被放在右邊一摞。然後,繼續對左右兩摞進行快速排序。直到進行快速排序的序列長度小於 2 (即序列中只有一個值或者空值)。

# quicksortimport randomdef quicksort(seq): if len(seq) < 2: return seq else: base = seq[0] left = [elem for elem in seq[1:] if elem < base] right = [elem for elem in seq[1:] if elem > base] return quicksort(left) + [base] + quicksort(right)seq = [9, 8, 7, 6, 5, 4, 3]random.shuffle(seq)# seq:[6, 4, 9, 3, 8, 5, 7]print(quicksort(seq))# 輸出:[3, 4, 5, 6, 7, 8, 9]

3. 冒泡排序

冒泡排序(順序形式),從左向右,兩兩比較,如果左邊元素大於右邊,就交換兩個元素的位置。其中,每一輪排序,序列中最大的元素浮動到最右面。也就是說,每一輪排序,至少確保有一個元素在正確的位置。這樣接下來的循環,就不需要考慮已經排好序的元素了,每次內層循環次數都會減一。其中,如果有一輪循環之後,次序並沒有交換,這時我們就可以停止循環,得到我們想要的有序序列了。

def bouble_sort(sequence): seq = sequence[:] length = len(seq) - 1 i = j = 0 flag = 1 while i < length: j = 0 while j < length - i: if seq[j] > seq[j + 1]: seq[j], seq[j + 1] = seq[j + 1], seq[j] flag = 0 j += 1 if flag: break i += 1 return seq

4. 選擇排序

選擇排序,每次選擇當前序列的最小值,將其與當前序列的第一個元素交換位置,每迭代一次,當前序列長度減一。迭代結束,即可得到有序序列。

def find_minimal_index(seq): min_elem = seq[0] count = 0 min_elem_index = count for elem in seq[1:]: count += 1 if elem < min_elem: elem, min_elem = min_elem, elem min_elem_index = count return min_elem_indexdef select_sort(sequence): # 選擇排序 seq = sequence[:] length = len(seq) for i in range(length): index = find_minimal_index(seq[i:]) seq[index + i], seq[i] = seq[i], seq[index + i] return seq

5. 去重序列重複元素

首先新建一個集合 set,對於序列中的元素,如果已經在集合中了,我們就不返回這個值。如果不在集合中,就向集合添加這個元素,並返回這個值。key 是函數名,通過修改 key,我們可以改變重複元素的判斷依據。比如對於下面這個序列:a = [{'a': 6, 'b': 4}, {'a': 6, 'b': 3}, {'a': 6, 'b': 4},{'a': 8, 'b': 12}]list(dedupe(a, lambda x: x['a']))這裏我們把 dedupe 設置爲,基於關鍵字 ‘a’ 對應值去除重複元素,也就是說集合中添加的元素爲關鍵字 ‘a’ 對應值。輸出爲:[{'a': 6, 'b': 4}, {'a': 8, 'b': 12}]list(dedupe(a, lambda x: (x['a'],x['b'])))這裏,集合添加的是關鍵字’a’和’b’對應值的元組。

輸出爲: [{'a': 6, 'b': 4}, {'a': 6, 'b': 3}, {'a': 8, 'b': 12}]

# Python高效編程def dedupe(sequence, key): # 依序去除重複元素 seen = set()items = sequence[:] for item in items: if key: seq = key(item) if seq not in seen:seen.add(seq) yield item

6. Vector

清華教授花一個月把Python所有基本用法歸納好了!末有驚喜

 

 

這一節,我們來實現一個簡單的 Vector 類。Vector 類有兩個屬性,爲 x,y 座標,即對應向量的橫縱座標。首先,實現重載 + 號的方法def __add__,及實現兩個向量的加法。具體做法是:將加號兩邊的 Vector 對象的 x, y值相加,得到新的 x, y值並且返回一個新的向量對象。__sub__方法實現了 Vector 對象的減法,和加法差不多。讓向量對象的對應屬性相減,並返回新的向量對象。__ads__方法,使得可以對實例進行 ads操作(即取橫縱座標的模)。__mul__方法,使得實例可以通過乘法進行伸縮的操作。__repr__與__str__方法使得打印對象更加美觀。

import math# Python高效編程class Vector(object): def __init__(self, x, y): self.x = xself.y = y def __add__(self, other): x = self.x + other.x y = self.y + other.y return Vector(x, y) def __sub__(self, other): x = self.x - other.x y = self.y - other.y return Vector(x, y) def __abs__(self): return math.sqrt(self.x ** 2 + self.y ** 2) def __bool__(self): return bool(self.x or self.y) def __mul__(self, times): return Vector(self.x * times, self.y * times) def __repr__(self): return 'Vector({}, {})'.format(self.x, self.y) __str__ = __repr__def main(): v1 = Vector(3, 5) v2 = Vector(4, 5) v3 = v1 + v2 v4 = v3 * 2 v5 = v2 - v1 print(v3) print(v4) print(abs(v3))print(v5)if __name__ == '__main__': main() # 輸出:# Vector(7, 10)# Vector(14, 20)# 12.206555615733702# Vector(1, 0)

7. 具名元組

具名元組(namedtuple) 是 python 標準庫 collections 中的工廠函數。它接受兩個參數,第一個參數表示類的名稱,第二個參數是類的字段名。後者可以是可迭代對象,也可以是空格隔開的字符串。然後,我們通過一串參數的形式將參數傳遞到構造函數中。這樣,我們既可以通過字段名訪問元素,也可以用索引訪問元素。

from collections import namedtupleToDo = namedtuple('ToDo', 'date content priority')t = ToDo(12, 'null', 1)print(t.date)print(t[1])# 輸出:# 12# null

下面是具名元組的演示程序:我們創建了一個 ToDoList 類,並且支持 + 、索引、切片與顯示等操作。並且通過格式化輸出,美化打印結果。

from collections import namedtupleToDo = namedtuple('ToDo', 'date content priority')class ToDoList: def __init__(self): self.item = [] def add(self, date, content, priority): self.item.append(ToDo(date, content, priority)) def _modify(self, item):self.item = item @property def _getitem(self): return self.item def __getitem__(self, pos): return self.item[pos] def __add__(self, other): item = self._getitem + other._getitem t = ToDoList() t._modify(item) return t def __repr__(self): items = self._getitem text = '{:<5}{:^10}{:^10}'.format('date', 'content', 'priority') fmt = '{:<5}{:^10}{:^10}' for item in items: text += ' ' text += fmt.format(item.date, item.content, item.priority) return text __str__ = __repr__def main(): t1 = ToDoList()t1.add(12, 'play', 0) t1.add(8, 'seek', 6) t2 = ToDoList() t2.add(4, 'sleep', 2) t3 = t1 + t2 print(t3)if __name__ == '__main__': main()# 輸出# date content priority #12 play 0 #8 seek 6 # 4 sleep 2

三、遞歸

1. 階乘

迭代停止條件:n < 2

# 階乘# n > 0def factor(n): return 1 if n < 2 else n * factor(n-1)

2. 序列和

迭代停止條件:序列爲空

# 和def naive_sum(seq): if not seq: return 0 else: return seq[0] + naive_sum(seq[1:])

3. 求序列長度

迭代停止條件:序列爲空

# 計數def naive_count(seq): if not seq: return 0 else: return 1 + naive_count(seq[1:])

4. 求序列最大值

迭代停止條件:序列爲空

# 最大值count = 1def naive_max(seq): global count global max_num if count:max_num = seq[0] count = 0 if not seq: count = 1 return max_num else: if seq[0] > max_num: seq[0], max_num = max_num, seq[0] return naive_max(seq[1:])

以上便是本次的全部內容,大家可以親自編程練練手。

下面爲大家分享一些乾貨,點擊:資料  ,領取!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章