廖雪峯 Python教程 筆記一

#Python基本語法
Python的應用範圍非常廣,至少要分爲:科學計算、腳本運維、爬蟲、業務系統(web,部分雲計算)等方向。
廖雪峯 Python教程的學習筆記
Python之所以簡潔,主要感覺到的是它代碼語法核函數上上沒有拘泥於固定的幾種格式,十分的靈活,定義出了各種語法操作(比如 a**b,a<b<c, try xxx with xxx),以及方便的函數等,像Java一定不採用符號操作,必須用字母寫方法,C有符號不提供那麼多方法。
###1、輸入輸出:input進行輸入,print進行輸出:
name = input('請輸入')
print('hello', name)
input返回值即輸入內容,可以傳入提示內容
— 注意想要輸入整數,使用age = input("請輸入年齡:"), 因爲Python無類型,所以默認輸入的是字符串,如果這時直接對age按整數處理,就會報錯。需要進行轉型的處理
age = int(age)
print輸出,可以傳入多種類型的參數,字符串,字面量數值或者變量:
— print(‘abc’,‘def’) //輸出abc def 其中的,相當於空格
print(‘abc’+‘def’) // 輸出abcdef
— print()輸出默認是帶換行的,想要不換行,使用print(“xxx”, end = “”) 即可, 3.x的版本上
還有seq = xxx, 代表逗號分隔符是哪個

###2、數據類型及運算
Python的基本數據類型有:
Python是動態類型語言,定義變量時不用再前面加上類型名稱,所以也沒有類型聲明,根據給出的值判斷是什麼類型。
1、空值 None 表示
2、布爾類型 True False表示
布爾類型的運算不用符號,用的是字母名稱!!有點不科學了
and、or和not三種

3、整數 10,9,8 等
Python可以直接處理任意大小的整數,和C、Java語言不一樣,
另外注意,用 / 表示浮點數除法,用 // 表示取整除(地板除),不管整數還是小數相除都會取向下整
4、浮點數
5、字符串
字符串可以使用’或"引起來,還可以用’’’ 三個單引號引起來,裏面的內容可以直接換行
這裏面的字符串和Java一樣的內部結構,是不可變對象
如print(’’’ 第一行
第二行’’’)
就會輸出
第一行
第二行
轉義:在字符串內部使用\x 進行轉義,一個爲了方便的操作,在’或"或’’'引起來的字符串前面加上r,裏面的轉義的字符就不轉義了

數據類型的轉型見前面有age = int(age) 這樣轉型,用的函數法處理,沒有像C或Java定義這門的語法

###3、字符串和編碼:
Python默認使用Unicode進行編碼,現代大多數的操作系統和語言都支持Unicode. Unicode 字符長度爲2個字節,能表示的字符仍然有限,且可能可能浪費內存,於是後面出現你UTF-8,它是變長的,顯然更爲靈活。所以一般情況下,讀入或寫出數據時都是以UTF-8爲標準。在內存中用數值表示字符,不同的編碼碼制不一樣,同一個字符的數值不同,最後讀出來的可能就是亂碼。所以在程序中對字符進行編碼轉換,也就是將內存中的表示數值轉換成對應碼制中的表示數值。

3.1 字符與編碼號轉換
ord(‘A’) 獲取某個字符的編碼
65
chr(66) 將整數轉換到對應的字符

3.2 字符串與byte轉換
使用
"xxx".encode("yyy") encode characters to byte array use the given encoding, the result be printed is asicii or hex number
"xxx".decode("yyy") parse byte array to characters use the given encoding,
it can contains a paramter which is used to ingonor the a small part of wrong bytes.like "xxx".decode("yyy", errors='ignore') ; otherwise the method will report an error

3.3 代碼格式
代碼文件也要聲明格式,寫在代碼中的字符才能被正確處理,可在源文件的開頭加上註釋,告訴python解釋器,代碼使用的格式,另外還必須要在編輯器或IDE中指定代碼使用的格式纔行
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

**3.4 字符串的基本方法 **
(1)len(‘xxx’) 返回字符串的長度,如果在前面加上(b’sdfsfsdfs’) 轉換成了byte的形式,就會返回byte數組,可見可以直接使用len()方法,不用像Java一樣一定要加上類名或者創建對象,那樣格式化,Python的代碼形式更爲靈活。

(2)格式化輸出,Python支持和C語言一樣的格式化輸出操作,有所優化,形式爲
'Hello, %s' % 'world'
"%d * %d = %0d "%(i, j, i * j) 匹配多個
用%連接形參和實參即可,形式上更簡潔了。 用%連接,很巧妙,代碼的語法跳出了C那樣的固定式的限制,顯得靈活自由。
另一個,它的%s,就想print語句一樣,可以格式化各種基本的數據類型。

# 打印9*9乘法表
for i in range(1, 10):
    for j in range(1, i+1):
        print("%d * %d = %0d "%(i, j, i * j), end='')
    print()

還可以使用字符串的format的方法,比如
'Hello, {0}, 成績提升了 {1:.1f}%'.format('小明', 17.125)
會輸出
'Hello, 小明, 成績提升了 17.1%'
格式爲{d:xxx},d代表第幾個參數,xxx代表附加處理

4. 集合:數組列表list和元組tuple、map的dict和集合set

Python數組也是很靈活的,它的集合類列表、字符串等,是可以直接判斷相等的,裏面所有的元素。

4.1 數組列表
** 定義和初始化 **
l = ['Michael', 'Bob', 'Tracy']
因爲動態類型,所以列表裏面可以放任意不同類型的數據,包括列表自身。比如:
L = ['Apple', 123, True]
s = ['python', 'java', ['asp', 'php'], 'scheme']
使用列表中列表相當於多維數組,用s[2][1]可以訪問數組中的數組

**元素訪問和修改 **
l[i] 訪問第i個
l[-i] 訪問倒數第ige
l[i] = x, 賦值
l.append(x); 末尾加入
l.insert(i, x); 插入
l.pop(); 刪除最後一個
l.remove(i); 刪除第i個

**4.2 元組 **
元組是不可變的數組,除了不可修改外,其它操作和數組基本一致,當然不可修改是指的它的元素指向的引用本身不能修改再指向其它,引用對應的對象內部是可以修改的。
一般情況下,能用tuple就用tuple,代碼更安全,更高效。
初始化方法:
t=('sdsd', 5.4, 6, None);
注意的是定義單元素tuple要加上,寫成
t=(5,);
不然如果是(5),那就變成數字5了。

4.3 相當於map的dict

定義和初始化:
dict的初始化有幾種方法

d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
d = [(a,1), (b,2), (c,3)]
d = {a:1, b:2, c:3}
d = zip(a,b) # a, b代表兩個列表

操作

d['Adam'];#訪問:這種方式只能訪問已經存在的值,不存在的訪問會拋出KeyError錯誤,可以先用if x in d 判斷
d.get('Thomas')
d.get('Thomas', -1) # -1 爲默認值
d['Jack'] = 88 賦值
d.pop('Bob')

使用map的注意是其key值必須是不可變對象,不然放進去之後變了就亂了,就找不到了等。同Java字符串以及整數、浮點數等基本類型可行。
另外,由於是無類型的,所以Python的key可以是不同類型

對於下標式訪問,d[xx],只能

4.4 set
創建方法
s={1,1,2,3} 這個和dict具有一致性,因爲map就是set的轉化
s = set([1, 2, 3])
s.add(4)
s.remove(4)
set可以看成數學意義上的無序和無重複元素的集合,因此,兩個set可以做數學意義上的交集、並集等操作,支持了
s1 | s2
s1 & s2

自然的在Python中也有淺拷貝和深拷貝,使用copy方法的時候要注意。

5.條件語句和循環語句

age = 3
if age >= 18:
    print('your age is', age)
    print('adult')
else:
    print('your age is', age)
    print('teenager')

age = 3
if age >= 18:
    print('adult')
elif age >= 6:
    print('teenager')
else:
    print('kid')

幾個不同:
(1) 用空格代替括號開始,:代表括號結束
(2) Python 使用縮進代替{}限定語句塊,縮進結束,代表語句塊結束。
(3)else if 協作elif

同樣的,對於循環語句Python也採用同樣的格式進行處理。
有2種寫法:
names = [‘Michael’, ‘Bob’, ‘Tracy’]
for name in names:
for num in range(10): # 迭代 0 到 9 之間的數字
for num in range(10,20): # 迭代 10 到 19 之間的數字
for letter in ‘Python’: # 迭代字符串

while(n > 0)

多重判斷或多重循環在裏面加上語句即可。

##二、函數
###1、定義函數
1.1 基本定義
和循環一樣,用:和縮進替代{},假設定義一個絕對值函數

my_abs(x):
    if x >= 0:
        return x
    else:
        return -x

如果在一個語句塊中想什麼也不做,使用pass,eg:

if a > 0:
   pass

如果不加pass的話會報錯

返回語句,由於Python無類型,所以不用聲明返回值得類型。因此,更進一步的,返回值得個數也可以不加限定了,使用Python的元組即tuple類型可以做到這點。

1.2 引用函數
你已經把my_abs()的函數定義保存爲abstest.py文件了,那麼,可以在該文件的當前目錄下啓動Python解釋器,用from abstest import my_abs來導入my_abs()函數,注意abstest是文件名(不含.py擴展名);

1.3 參數類型檢查
由於Python是無類型的,但是方法可能傳入任何類型的參數進來,所以方法的定義中必須手動檢查參數類型,否則就會出錯。

def my_abs(x):
    if not isinstance(x, (int, float)):
        raise TypeError('bad operand type')
    if x >= 0:
        return x
    else:
        return -x

用內置函數 isinstance(x, (int, float,…))檢查

2 函數的參數

函數也可以賦值給一個變量,
Python的函數參數較爲靈活和複雜,有基本參數,默認參數,{可變參數,{關鍵字參數, 命名關鍵字參數}}。
2.1 默認參數
默認參數就是參數含有默認值,調用方法時可以對該參數傳遞值,也可不對改參數傳遞值。要求必須把必選參數放在參數序列前面,把默認參數放在參數序列的後面,這樣便於編譯器處理,也便於使用理解。
默認參數還可以在傳參時指定傳給誰,在前面加上參數名=xxx即可,表示將實參傳遞給哪個具體的形參,這樣就可以不按定義的默認參數的順序傳遞默認參數了。
eg:
print("xcxc", end ="")就是這種調用

使用默認參數可以達到增加函數擴展性和簡潔性的效果,比如要對原來的函數增加一個參數,又不影響以前的調用代碼,使用默認參數即可。

Python默認參數的坑 默認參數中的默認值是可變的!!!
加入定義方法時對默認參數賦的值是一個可變對象,比如

def  add_end(L=[]):
       L.append('END')
       return L

Python內部的處理應該是,在程序初始化是時候,創建一個對象X,並將它複製給L, 然後返回L。但是當你再次使用該函數時,內部不會再創建一個對象,而是使用最開始創建的那個對象X,所以當你第二次調用add_end()時,會有兩個’END’,第n次調用時有n個’END’,爲避免這種問題,所以默認參數默認值必須使用不可變對象

2.2 可變參數
可變參數,就是在方法中聲明一個參數,此參數可以代表0-n個參數,這時可以傳遞0-N個參數進去,如果想傳遞集合進去,使用
l=set[“aaa”,“bbb”, ‘ccc’]
method(*l)
即可
可變參數在函數調用時會自動組裝成一個tuple。

2.3 關鍵字參數
1、其實前面的可變長參數相當於傳遞一個列表到函數中,這裏的關鍵字參數就相當於一個map到函數中,如下:

def person(name, age, **kw):
    print(name, age, kw)

person("小明", 5, country = "china", gender = "男")

m = {"country" : "china", "gender" : "男"}
person("小明", 5, **m)

可以看出,直接傳遞key = value的形式,或者傳遞組裝好的map(前面加上 **)進去都行,直接傳遞的形式更爲簡潔

2.4 命名關鍵字參數
還有一種叫做命名關鍵字參數,和默認關鍵字參數比較類似,如下:

def person(name, age, *, city, job):
    print(name, age, city, job)

要表達命名關鍵字參數時,必須加一個間隔符用來表示後面的是關鍵字序列,也即key的序列,這個間隔符用*表示,或者一個可變參數也可代替

命名參數也可以有自己的默認值,就行默認參數一樣,不同的是,命名參數傳值時必須指明傳給那個命名關鍵字,而默認參數不一定需要,並且所以的不含默認值得命名參數都需要有隻,所以命名參數相對於默認參數的優點是,操作更爲明確。

2.4 參數的組合
由於有多種參數,他們之間的組合就比較講究了,不然使用起來很容易混亂和出錯。
參數定義的順序必須是:必選參數、默認參數、可變參數、命名關鍵字參數和關鍵字參數。
雖然後面幾種可以改變順序,但是最好不要那樣做,不然很容易混亂。
另外, 雖然可以組合多達5種參數,但不要同時使用太多的組合,否則函數接口的可理解性很差。
另外,函數還有這樣的語法:
定義

def f1(a, b, c=0, *args, **kw):
    print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)

然後調用

>>> args = (1, 2, 3, 4)
>>> f1(*args)

如果在list的元素個數足夠的情況下了,解釋器會逐一取出list的項填入到函數參數中,(不夠會報錯),對於關鍵字參數,則使用dict有一樣的語法。

##3、列表高級特性、操作
###3.1 切片
切片就是獲取集合的一個子集

L = [1,2,3,4,5,6,7,8,9,10]

L[a:b]表示獲取L的下標a到b-1之間的元素的集合,如果a或b無值,則表示從0開始或到最後一個。a,b 可以使用負號的,b>=a 時,返回空,a或者b不在範圍內都沒事。
還有,可以間隔取數,如
L[a🅱️n] 表示每間隔n個數取一個數出來。

3.2 迭代

(1)正如Java的迭代器,只有對象是可迭代的,就能使用迭代語句進行迭代

>>> from collections import Iterable
>>> isinstance('abc', Iterable) # str是否可迭代

用上面的語句判斷即可

迭代dict ,默認迭代的是key,使用d.values()可以迭代value,使用d.items(),可以迭代key-value對

使用enumerate(x)函數可以同時迭代下標和值
for i, value in enumerate([‘A’, ‘B’, ‘C’]):

(2)迭代器Iterator
區別,迭代器對象與可迭代對象是不一樣的,Iterator提供next()方法,返回下一個值,此方法是惰性的,只會計算下一個值。通過Iterablde的iter方法獲得他的一個Iterator對象。

3.3 列表生成式

Python的列表生成式,功能強大,豐富
L = [x * x for x in range(1, 11) if x % 2 == 0]
如上,使用一行表達式生成列表,range(a,b) 後面表示的是對元素的過濾方式,for前面加一個表達式,表示對元素的計算式,這樣生成最終的列表。

對於Map等的,還可以使用多個變量,就更強大了。

還可以多層循環,需要計算時就將內層的變量都可以寫到兩端
[m + n for m in ‘ABC’ for n in ‘XYZ’]

3.4 生成器

用於生成有限或無限個元素,並不是一次生成,而是調用一次,生成一次。可以使用next(g)方法,讓它生成下一個元素。也可以在for循環中使用。
創建生成器的方法:
(1)直接使用 g = (x * x for x in range(10)) 這種生成式,把生成列表時用的[]變成()括號,即可創建一個生成器,它不再是一個列表,不能使用列表相關的方法。而是按生成器的來使用。
(2)使用函數對象創建:
比如

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1
    return 'done'

調用next()時,遇到yield就返回一次值,然後函數暫停在這裏,下次再調用next()函數從這裏開始執行,直到遇到下一個yield,然後暫停,返回值。顯然,對於循環中的next(),會循環的遇到yield。
含有yield的函數可以稱作生成器函數,調用它之後返回的是一個生成器,並不是普通的返回值。比如
m = fib(6);
next(m);
或者
m = fib(b).__next__ #其中的__next_是生成器函數擁有的一個屬性
m()
這兩種方法讓生成器進行下一次執行
可以直接對列表進行相加拼接 如 l[0:2] + s[8:]

這裏可看出,Python的函數是能記錄狀態的,這和C中的函數是不一樣的。在Python中它的實質和對象是沒有區別的

重點內容

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