1. 程式人生 > >【Python】程式設計筆記4

【Python】程式設計筆記4

程式碼越少,開發效率越高。

高階特性

一、切片(slice)

1、list 的切片

## L 是 0 - 99 的數列
L = list(range(100))
print(L)
print(L[:10])     # 前 10 個數
print(L[-10:])    # 後 10 個數
print(L[10:20])   # 前 11-20 個數:
print(L[:10:2])   # 前 10 個數,每兩個取一個
print(L[::5])     # 所有數,每 5 個取一個
print(L[:])       # 原樣複製一個 list

輸出結果

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
[0, 2, 4, 6, 8]
[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]

2、tuple、字串的切片

t = (0,1,2,3,4,5)
print(t[:3])
s = 'ABCDEFG'
print(s[:3])
print(s[::2])

輸出結果

(0, 1, 2)
ABC
ACEG

二、迭代

Python 中給定一個 list 或 tuple 或其他可迭代的物件(有無下標就可以迭代),通過 for ... in 來遍歷,這種遍歷稱為迭代( Iteration)

1、字典的迭代

dict 的儲存不是按照 list 的方式順序排列,所以,迭代出的結果順序很可能不一樣。

預設情況,dict 迭代的是 key。

d = {
'a':1, 'b':2, 'c':3} for key in d: print(key) ## 迭代 values for value in d.values(): print(value) ## 同時迭代 key 和 value for k,v in d.items(): print(k,v)

輸出結果

a
b
c
1
2
3
a 1
b 2
c 3

2、字串的迭代

for ch in 'ABC':
    print(ch)

3、可迭代物件判斷

通過 collections 模組的 Iterable 型別判斷。

from collections import
Iterable print(isinstance('abc', Iterable)) # str 是否可迭代 print(isinstance([1, 2, 3], Iterable)) # list 是否可迭代 print(isinstance(123, Iterable)) # 整數是否可迭代

輸出結果

True
True
False

通過 enumerate 函式可以把一個 list 變成索引-元素對
==》在 for 迴圈中同時迭代索引和元素本身。

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

輸出結果

0 A
1 B
2 C

常用:for 迴圈裡,同時引用了兩個變數

for x, y in [(1,1),(2,4),(3,9)]:
    print(x, y)

輸出結果

1 1
2 4
3 9

三、列表生成式( List Comprehensions)

## [1x1, 2x2, 3x3, ..., 10x10]
print([x * x for x in range(1, 11)])
print([x * x for x in range(1, 11) if x % 2 == 0])
## 兩層迴圈
print([m + n for m in 'ABC' for n in 'XYZ'])

## 列出當前目錄下的所有檔案和目錄名
import os
# os.listdir 可以列出檔案和目錄
print([d for d in os.listdir('.')])

d = {'x':'A', 'y':'B', 'z':'C'}
print([k + '=' + v for k, v in d.items()])

L = ['Hello', 'World', 'IBM', 'Apple']
print([s.lower() for s in L])

## 過濾掉非str型別
L1 = ['Hello', 'World', 18, 'Apple', None]
L2 = [s for s in L1 if isinstance(s, str)]
print(L2)

輸出結果

[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
[4, 16, 36, 64, 100]
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
['1.py', '2.py', '3.py', '4.py']
['x=A', 'y=B', 'z=C']
['hello', 'world', 'ibm', 'apple']
['Hello', 'World', 'Apple']

四、生成器( Generator)

一邊迴圈一邊計算的機制,稱為生成器。

方法一——()

將列表生成式中 [] 改成 (),使用 for迴圈 訪問元素

g = (x * x for x in range(10))
print(g)
for n in g:
	print(n)

輸出結果

<generator object <genexpr> at 0x0000017EFFAE5D00>
0
1
4
9
16
25
36
49
64
81

==》generator 函式的“呼叫”實際返回一個 generator 物件

方法二——yield

如果一個函式定義中包含 yield 關鍵字,則該函式是一個 generator。

以斐波拉契數列( Fibonacci)為例:

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a+b
        n = n + 1
    return 'done'
print(fib(6))
## 元素的訪問
for n in fib(6):
	print(n)

輸出結果

<generator object fib at 0x000001A8A31EA1A8>
1
1
2
3
5
8

2、Generator 的理解

generator 和函式的執行流程不一樣。

  • 函式是順序執行,遇到 return 語句或者最後一行函式語句就返回。
  • generator 函式,在每次呼叫 next() 的時候執行,遇到 yield 語句返回,再次執行時從上次返回的 yield 語句處繼續執行。

3、楊輝三角形

def triangles():
    N = [1]
    while True:
        yield N
        N.append(1110)
        N = [N[i] + N[i-1] for i in range(len(N))]
n = 0
for t in triangles():
    print(t)
    n = n + 1
    if n == 10:
        break

輸出結果

[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
[1, 5, 10, 10, 5, 1]
[1, 6, 15, 20, 15, 6, 1]
[1, 7, 21, 35, 35, 21, 7, 1]
[1, 8, 28, 56, 70, 56, 28, 8, 1]
[1, 9, 36, 84, 126, 126, 84, 36, 9, 1]

五、迭代器

1、可迭代物件——Iterable

可迭代物件(Iterable):可以直接作用於 for 迴圈的物件的統稱。

包括:集合資料型別,如 list、 tuple、 dict、 set、 str 等; generator,包括生成器和帶 yield 的 generator function。

判斷是否是 Iterable 物件

isinstance()函式來判斷

from collections import Iterable
print(isinstance([], Iterable))
print(isinstance({}, Iterable))
print(isinstance('abc', Iterable))
print(isinstance((x for x in range(10)),Iterable))
print(isinstance(100, Iterable))

輸出結果

True
True
True
True
False

2、迭代器——Iterator

生成器不僅可用於 for 迴圈,也可被 next() 函式不斷呼叫並返回下一個值,直到最後越界丟擲 StopIteration 錯誤表示無法繼續返回下一個值為止。
==》next()函式呼叫並不斷返回下一個值的物件稱為迭代器。

判斷是否是 Iterable 物件

isinstance()函式來判斷

from collections import Iterator
print(isinstance([], Iterator))
print(isinstance({}, Iterator))
print(isinstance('abc', Iterator))
print(isinstance((x for x in range(10)),Iterator))

輸出結果

False
False
False
True

3、Iterable vs. Iterator

生成器既是 Iterable 又是 Iterator 物件
但 list、 dict、 str 雖然是 Iterable,卻不是 Iterator。

轉換:Iterable ==》Iteraor 用 iter() 函式

print(isinstance(iter([]), Iterator))
print(isinstance(iter({}), Iterator))
print(isinstance(iter('abc'), Iterator))

輸出結果

True
True
True
思考:為什麼 list、 dict、 str 等資料型別不是 Iterator?

這是因為 Python 的 Iterator 物件表示的是一個數據流, Iterator 物件可以被 next()函式呼叫並不斷返回下一個資料,直到沒有資料時丟擲 StopIteration 錯誤。可以把這個資料流看做是一個有序序列,但我們卻不能提前知道序列的長度,只能不斷通過 next()函式實現按需計算下一個資料,所以 Iterator 的計算是惰性的,只有在需要返回下一個資料時它才會計算。
Iterator 甚至可以表示一個無限大的資料流,例如全體自然數。而使用list 是永遠不可能儲存全體自然數的。