1. 程式人生 > >廖雪峰Python教程筆記(一)

廖雪峰Python教程筆記(一)

感謝廖老師精彩的Python教程,收益良多,感謝感謝!

整理筆記,以備後續複習,第一部分一直到模組結束,整理如下,其中大量的單引號是有問題的,由於word直接打的,嫌麻煩,沒有都進行修正,請見諒

1、a = ‘XYZ’ 的過程是先在記憶體中建立一個’XYZ’字串,然後建立一個名為a的變數,並指向’XYZ’

2、布林值:True  和 False ,注意大小寫

3、空值:None

4、變數本身型別不固定稱為動態語言

5、常量 就是不能變的變數,python中通常用全部大寫表示名字表示一個常量,但是其本身任然是個變數,你想改也沒人攔得住

6、除分兩種,/ 這種得到的結果是浮點數 // 地板除,類似於取整  %求餘

7、輸出,print(‘AB’, ‘LOVE’, ‘CD’) 輸出結果是AB LOVE CD

8、輸入 name = input()

9、每一行都是一個語句,語句以:結尾的是一個語句塊

10、始終堅持四個空格

11、python大小寫敏感

12、用print(r‘\t’)  這樣可以不用轉義字元了,不然需要轉義

13、用’’’ 可以標識輸出多行 print(‘’’ line1

Line2’’’)

14、字元編碼,最開始英文的時候ascii(一個位元組), 中文GB2312, 所有的 (各國語言)unicode(一般是兩個位元組表示一個字),然後節約精神導致了utf-8:可變長編碼,英文1個位元組,中文一般三個位元組,很生僻的4-6(主要如果是全英文的話,用unicode太浪費了)

所以,當傳輸的文字中有大量的英文字元,那就用utf-8

15、記憶體中都是unicode的編碼方式,當儲存磁碟或者傳輸時,轉成uft-8

16、如從記事本中讀入記憶體又寫回,是先從文字讀取utf-8,轉成unicode到記憶體,編輯完成後,儲存的時候,又轉成uft-8

17、python3裡面都是unicode的  ord()獲取字元整數表示,chr()編碼轉換成對應字串

\u4e2d表示的是unicode的編碼形式,ord()後得到的值就是unicode對應的值的十進位制表示

18、根據上一條,如果要在網路上傳輸或者存入磁碟,就涉及到str和bytes的轉換

bytes可以用b’ABC’表示 str通過encode()轉成指定編碼的bytes

如:’ABC’.encode(‘ascii’) 或 ‘中文’.encode(‘utf-8’)

如果從網路上讀取了位元組流或磁碟讀取了資料,讀取的是bytes,變成str要用decode

如:b’ABC’.decode(‘ascii’) 或b‘\xe4\xb8\xad’.decode(‘utf-8’, errors=’ignore’) errors不是必須的,寫了可以忽略錯誤位元組

19、計算str中包含的字元,用len(),如果是bytes型別的話,len()計算的是位元組數

20、python頭,指定是可執行程式和指定編碼

#!/usr/bin/env python3

# -*- coding: utf-8 -*-

21、格式化   佔位符:%s 字串  %d 整形 %f 浮點型  %X 十六進位制

還可以指定補0和寬度限制%04d 寬度是4,不夠的補充0

%.9f  小數點後保留9位

%% 輸出百分號

22、另一種格式化 format()

23、增長百分比,計算公式是(當前-之前)/之前

24、如果沒有特殊要求,轉換的時候,牢記使用utf-8

25、list 有序集合,可以下標訪問,len獲取元素個數,最後一個可以用-1做索引,-2等類似

append()追加到最後clas.append(‘ee’)

insert()指定到索引的位置 clas.insert(2, ‘cc’)  #切記是從0開始的,2指的是第三個位置

pop()刪除末尾

pop(i)刪除指定位置

賦值給對應下標直接把對應下標值替換掉

list裡面的元素型別可以不一樣 L = [‘app’, 111, True]

list元素可以是一個list  M = [[1, ‘bb’], ‘aaa’, L]

26、tuple 和list類似,但是一旦初始化就不能修改

classmates = (‘aa’, ‘bb’, ‘cc’)

只有一個元素的tuple,要用clss = (1,) 切記一定要加逗號,否則會被當成計算結果的

cla = (‘A’, ‘B’, [C, D]) tuple裡面的list的值是可以變的 也就是cla[2][0] cla[2][1]可變,所謂的不可變是指向不可變,但是list本身可變,所以還是可以變化

由於tuple不可變,所以程式碼更安全,能用tuple代替list就代替

27、判斷  if elif else,切記後面都要加冒號

if age >= 6:

    do something

elif age >18:

    do something

else:

    do something

28、input()返回的都是str,所以如果是輸入的int型別的,那就要用int(s)轉一下

s = input(‘birth:’)

birth = int(s)

29、迴圈

for x in names:

range(n) 生成從0 到 n-1的序列

while 條件:

30、break提前跳出迴圈 ,continue跳過本次,直接開始下一次

31、dict 字典,其他語言中的map,使用鍵值(key-value)儲存

d = {‘AA’:11, ‘BB’:22, ‘CC’:33}

d[‘DD’] = 44 直接就把新的key加進去了

d.get(‘AA’) 不存在返回None 可以指定當不存在時候的返回值 d.get(‘AA’, -1)

pop(key) 刪除指定key-value對

dict內部存放的順序和key放入的順序無關

32、dict 比較 list 優點,查詢插入快,不會隨著key增加而變慢,缺點是佔用記憶體大

dict 空間換時間,可以用在需要高速查詢的地方

dict的key是不可變物件,因此可以用字串、整數做key,不能用list做key

33、set 和dict類似,一組key的集合

建立,需要提供list作為輸入集合 s = set([1,2,3]) key是不能重複的,加了重複的相當於沒加

add(key)可以新增元素到set

s = set([1,2,3])

s.add(4)

remove(key) 刪除元素

set相當於集合,可以做交、或

s1 = set([1,2,3])

s2 = set([2,3,4])

s1 & s2

s1 | s2

34、不可變物件

對於不變物件來說,呼叫物件自身的任意方法,都不會改變物件自身的內容,相反,這些方法會建立新的物件並返回,所以不可變物件永遠不可變

35、資料型別轉換  int() float() str() bool()

36、函式名也可以賦值給一個變數 如 a = abs  a(-1) 相當於給函式起了個別名

37、定義一個什麼事情都不做的空函式,可以用pass語句

def nop():

    pass

38、isinstance()  可以判斷第一個引數是不是第二個引數裡面的型別,第二個引數可以是個tuple

eg: isinstance(x, (int, float))

39、python返回多個值的時候,其實是返回的一個tuple,只是語法上一個tuple可以省略括號

40、函式執行完畢,也沒有return 則 自動 return None

41、一元二次方程的解 https://gss0.baidu.com/94o3dSag_xI4khGko9WTAnF6hhy/zhidao/wh%3D600%2C800/sign=b1668adbb30e7bec238f0be71f1e9500/472309f790529822fa69a717dcca7bcb0b46d488.jpg

42、可以指定預設引數,必須必選引數在前,預設引數在後

def power(x, y=2, z=4)

也可以不按順序提供部分預設引數

power(1, z=5)

43、預設引數大坑,一定不能指向可變的引數,如list

eg:def add_end(L = []):

            L.append(‘END’)

            return

可以更改成如下:

def add_end(L = None):

    if L is None:

        L = []

    L.append(‘END’)

    return L

44、不變物件的優勢

不能改,發生錯誤的可能大大降低

多工的時候,可以同時讀

45、可變引數,定義引數的個數可變的函式

def calc(*number): 這樣就可以了

46、如果已經有了一個list或者tuple,直接呼叫calc(*nums) 即可

47、關鍵字引數  ** 可以提供dict型別的引數

48、命名關鍵字引數

def person(name, age, *, city, job): 只接收city和job作為關鍵字的引數

49、任意函式,都可以通過類似func(*args, **kw)形式呼叫,無論引數如何定義

50、*args是可變引數,接收tuple    

**kw是關鍵字引數,接收dict

51、切片 L = [‘AA’, ‘BB’, ‘CC’]

L[0:3] 從0開始取,但是不包括3 獲取的是0 1 2

0可以省略,同時也可以倒數取值 L[-2:]

倒數第一個元素的索引是-1

所以後10個是L[-10:]

還可以前10個,每兩個取一個 L[:10:2]

L[::5] 所有的每五個取一個

L[:] 原樣賦值

52、使用切片寫trim() 去除頭尾的空格

def trim(s):

    while(s[:1] == ‘ ’):

        s = s[1:]

    while(s[-1:] == ‘ ’):

        s = s[:-1]

    return s

53、迭代

給定一個list或者tuple,我們通過for迴圈遍歷,這種遍歷稱為迭代

54、dict的迭代

dict預設迭代的是key       for key in d:

dict想迭代value               for value in d.values()

dict想兩個都迭代             for k,v in d.items()

55、判斷一個物件是可迭代物件,用collections 的Iterable型別判斷

from collections import Iterable

isinstance(‘abc’, Iterable)

56、list想同時迭代索引(下標)和元素本身

for i,v in enumerate([‘A’, ’B’, ’C’])

print(i, v)

輸出的結果會是 0 A\n1 B\n2 C(回車用\n代替了)

57、列表生成式List Comprehensions,可以建立list的生成式

[x * x for x in range(1,11)] 能生成 [1,4,9,…,100]

注意:range是不包括最右邊的邊界的

58、可以加上if判斷,篩選出你想要的

[x * x for x in range(1,11) if x%2 == 0] 這個結果是僅偶數的平方

59、兩層迴圈生成全排列

[x+y for x in ‘ABC’ for y in ‘XYZ’]

60、列出當前目錄下所有檔案和目錄名

import os

[d for d in os.listdir(‘.’)]

61、列表生成式也可以使用兩個變數生成list

d = {‘x’: ‘A’, ‘y’:’B’}

[x + ‘=’ + y for x, y in d.items()]

62、所有list變小寫

L = [‘Hello’, ‘World’]

[s.lower() for s in L]

63、L2 = [s.lower() for s in L1 if isinstance(s, str)] 只處理是str的防止出錯

64、生成器,一邊迴圈一邊計算的機制 generator

65、生成器建立方法一

生成式的中的[] 變為()

列印每一個元素使用next() ,eg:next(a) 最後丟擲StopIteration錯誤無法繼續

或者for迴圈,因為generator也是可迭代物件

66、yield 定義generator的另一種方法,函式定義中包含yield-》generator

呼叫的時候還是用for迴圈

67、可以直接作用於for迴圈的物件統稱為可迭代物件Iterable

list tuple dict set str 都是Iterable

68、可以被next()函式呼叫並不斷返回下一個值的物件成為迭代器Iterator

生成器都是Iterator物件,但是list dict str雖然是Iterable,但不是Iterator

變成Iterator 可以用iter()函式

69、Iterator物件表示的是一個數據流,是惰性的,只有需要返回下一個資料的時候才計算

70、python的for迴圈本質上是通過不斷呼叫next()函式實現的

71、函式名也是變數

f = abs

f(-1)

72、abs函式實際上是定義在import builtins模組,更改abs後,想讓abs變數的指向在其他模組也生效

用import builtins;builtins.abs = 10

73、傳入函式,一個函式接收另一個函式作引數,這種函式稱為高階函式

def add(x,y,f):

    retrun f(x) + f(y)

74、編寫高階函式,就是讓函式的引數能夠接收別的函式

75、把函式作為引數傳入,這樣的函式成為高階函式,函數語言程式設計就是指這種高度抽象的程式設計正規化

76、map()函式接收兩個引數,一個是函式,一個是Iterable,map將傳入的引數一次作用到序列的每個元素,並把結果作為新的Iterator返回

map()第一個引數是f,即函式物件本身,返回的是Iterator,所以用list()函式轉換下,可以把結果返回成list

def f(x):

    return x * x

r = map(f, [1,2,3])

list(r)

77、map()作為高階函式,把運算規則抽象了,比如把list所有數字轉字串

list(map(str, [1, 3, 4]))

78、reduce() 作用在一個序列[x1, x2, … ]上,函式接收兩個引數,reduce把結果序列和序列的下一個元素累計

reduce(f, [x1, x2, x3]) = f(f(x1, x2), x3)

79、序列求和

from functools import reduce

def add(x, y):

    return x+y

reduce(add, [1, 3, 5, 7, 9])

80、[1, 3, 5, 7]轉成整數1357

from functools import reduce

def fn(x, y):

    return x * 10 + y

reduce(fn, [1, 3, 5, 7])

81、str轉int

from functools import redece

def fn(x, y):

    return x * 10 + y

def char2int(s):

    digits = {'0': 0, '1': 1, '2': 2, '3': 3,'4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}

    return digits[s]

reduce(fn,map(char2int, ‘123675’))

82、上面的整理成函式(函式裡面可以巢狀函式)

from functools import reduce

DIGIT = {'0': 0, '1': 1, '2': 2, '3': 3,'4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}

def str2int(s):

def fn(x,y):

    return x * 10 + y

def char2int(c):

    return DIGIT[c]

reduce(fn, map(char2int, s))

上面還可以用lambda函式做一個簡化

83、**表示乘方

eg 10 **3 #表示10的3次方

84、filter()用於過濾序列,也接收一個函式,一個序列,作用於每個元素,根據True還是False決定留還是丟,如下刪掉偶數

def is_odd(n):

    return n%2 == 1

list(filter(is_odd, [1, 2, 3, 4]))

85、刪掉空字串

def not_empty(s):

    return s and s.strip()

list(filter(not_empty, [‘A’,’ ’, ‘C’, ‘   ’]))

86、生成素數

首先生成所有從3開始的奇數

def _odd_iter():

    n = 1

    while True:

        n = n + 2

        yield n

定義一個篩選函式

def _not_divisible(n):

    return lambda x:x %n > 0

最後,定義一個生成器,生成素數

def primes():

    yield 2  #先生成個2,因為素數佇列是從3開始的

    it = _odd_iter() #初始序列

    while True:

        n = next(it)

        yield n

        it = filter(_not_divisible(n), it)

87、判斷回數

def is_palindrome(n):

    return str(n) == str(n)[::-1] #取反操作,牛掰

89、排序演算法sorted(),也是高階函式,可以接收一個key函式來實現自定義的排序

sorted([-1, 2,6,-3], key=abs)

結果[-1, 2, -3 ,6]

key指定的函式會作用於list的每一個元素上,並根據key函式返回結果排序,然後用sorted()函式按照新的list排序,然後按照對應關係返回list相應的元素

90、實現忽略大小寫的排序

sorted(['bob', 'about', 'Zoo', 'Credit'], key = str.lower)

91、反向排序,加上第三個引數reverse=True

sorted(['bob', 'about', 'Zoo', 'Credit'], key = str.lower, reverse=True)

92、函式作為返回值

def lazy_sum(*args):

    def sum():

        ax = 0

        for n in args:

            ax = ax + n

        return ax

    return sum  #直接把函式返回了

使用的時候, f = lazy_sum([1,2,3,7,9]) 這時候不計算,只是返回個函式

呼叫f() 才計算

內部函式可以引用外部的引數和區域性變數,每次呼叫都會返回新的函式

93、函式中定義函式,內部函式可以引用外部函式的引數和區域性變數,當外部函式返回內部函式時,相關的引數和變數都儲存在返回的函式中,這種程式結構稱為閉包

94、返回閉包的時候,要牢記一點,返回函式不要引用任何迴圈變數,或者後續會發生變化的變數(因為返回的函式是到呼叫的時候才執行的,如果之前變數有變化,那結果也會變)

95、如果非得呼叫變數,那麼再定義一個函式,把引數繫結到迴圈變數當前的值

def count():

    def f(j):

        def g():

            return j * j

        return g

    fs = []

    for i in range(1, 3):

        fs.append(f(i))

    return fs #返回一個函式的list

96、匿名函式lambda,限制是只能有一個表示式,不用寫return

好處是不用擔心函式名衝突

可以把匿名函式賦值給一個變數,後續可以呼叫變數

可以把匿名函式作為返回值返回

def build(x,y):

    return lambda: x*x + y*y #這裡就不用加引數了

97、在程式碼執行期間動態增加功能的方式,稱為“裝飾器” Decorator,就是重新定義這個函式

def log(fn):

    @functools.wraps(fn)

    def wrapper(*args, **kw):

        print(“%s run” % fn.__name__)

        return fn(*args, **kw)

    return wrapper

98、偏函式Partial (偏愛,把偏愛的引數給固定死)把一個函式的某些引數固定住(設定上預設值),返回一個新的函式

import functools

int2 = functools.partial(int, base=2) #直接就變成了int 2預設2進位制轉換。

99、模組

一個abc.py檔案就是一個名字叫abc的模組,xyz.py檔案是一個名字叫xyz的模組

如果這兩個模組和其他的模組名衝突了,我們可以通過包來組織模組,避免衝突,方法為選擇一個頂層包名,按照如下目錄存放:

mycompany

|-- __init__.py  #必須存在,否則,Python會把目錄當成普通目錄,而不是包

|-- abc.py

|-- xyz.py

引入包後,只要頂層包名不和別人衝突,那所有模組都不會衝突

abc.py模組名變為mycompany.abc

xyz.py模組名變為mycompany.xyz

__init__.py 本身就是一個模組,模組名為mycompany ,可以是空檔案

自己建立的模組不能和Python自帶的模組名稱衝突,檢查方法直接在Python互動環境執行import abc,若成功則說明系統存在此模組

100、要新增自己的搜尋目錄,兩種方法

第一種直接修改sys.path,該方法執行時修改,執行結束失效

import sys

sys.path.append(‘/users/Michael/my_py_scripts’)

第二種設定環境變數PYTHONPATH