天天看點

[python文法] 進階特性[python文法] python進階特性

[python文法] python進階特性

文章目錄

  • [python文法] python進階特性
    • 一、切片
    • 二、疊代
    • 三、清單生成式
    • 四、生成器
    • 五、疊代器

一、切片

  • 切片的正常用法不再贅述,除了正常的切片功能,還可以在切片的基礎上每個N個元素取一個;
  • 以下是每隔2個元素取一個
l = range(10)
for i in l[::2]:
    print(i)
    
0
2
4
6
8
           

二、疊代

用for周遊list、tuple等可周遊對象,這種周遊就叫做疊代

在Python中,疊代是通過

for ... in

來完成的,而很多語言比如C語言,疊代list是通過下标完成的,比如Java代碼:

for (i=0; i<list.length; i++) {
    n = list[i];
}
           
  • python中隻要是可疊代對象,都可以通過for來周遊;通過collections子產品的Iterable類型判斷是否可疊代
>>> from collections import Iterable
>>> isinstance('abc', Iterable) # str是否可疊代
True
>>> isinstance([1,2,3], Iterable) # list是否可疊代
True
>>> isinstance(123, Iterable) # 整數是否可疊代
False
           
  • Python内置的

    enumerate

    函數可以把一個list變成索引-元素對,這樣可以同時擷取到index和value
>>> for i, value in enumerate(['A', 'B', 'C']):
...     print(i, value)
...
0 A
1 B
2 C
           

三、清單生成式

簡單的用法就不說了,記錄一些特殊的用法

  • 多層循環
>>> [m + n for m in 'ABC' for n in 'XYZ']
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
           
  • if ... else

    的使用
    1. 在for之前時,必須包含else。

      因為**

      for

      前面的部分是一個表達式,它必須根據

      x

      計算出一個結果**。而表達式:

      x if x % 2 == 0

      ,它無法根據

      x

      計算出結果,因為缺少

      else

      ,必須加上

      else

    不加

    else

    報錯:
>>> [x if x % 2 == 0 for x in range(1, 11)]
  File "<stdin>", line 1
    [x if x % 2 == 0 for x in range(1, 11)]
                       ^
SyntaxError: invalid syntax
           
>>> [x if x % 2 == 0 else -x for x in range(1, 11)]
[-1, 2, -3, 4, -5, 6, -7, 8, -9, 10]
           
  1. for之後不用

    else

    因為for後面是篩選條件,用來判斷目前的x要不要傳回,是以不用else
    >>> [x for x in range(1, 11) if x % 2 == 0]
    [2, 4, 6, 8, 10]
               

四、生成器

  • 生成器的典型特點:按照某種算法推算出來,那循環的過程中不斷推算出後續的元素;不必建立完整的list,進而節省大量的空間;
  • 生成器的建立

    要建立一個generator,隻要把一個清單生成式的

    []

    改成

    ()

    ,就建立了一個generator:
    >>> L = [x * x for x in range(10)]
    >>> L
    [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
    >>> g = (x * x for x in range(10))
    >>> g
    <generator object <genexpr> at 0x1022ef630>
               
    使用()在清單長度很大的時候,可以節約大量的記憶體,提高性能
  • 可以直接用for周遊生成器,不一定非要用next; next還要捕獲最後一個空元素的異常
    >>> g = (x * x for x in range(4))
    >>> for n in g:
    ...     print(n)
    ... 
    0
    1
    4
    9
               
  • 比如,著名的斐波拉契數列(Fibonacci),除第一個和第二個數外,任意一個數都可由前兩個數相加得到:

    1, 1, 2, 3, 5, 8, 13, 21, 34, …

    斐波拉契數列用清單生成式寫不出來,但是,用函數把它列印出來卻很容易:

    def fib(max):
        n, a, b = 0, 0, 1
        while n < max:
            print(b)
            a, b = b, a + b
            n = n + 1
        return 'done'
               
    生成器的方式的實作,要把

    fib

    函數變成generator,隻需要把

    print(b)

    改為

    yield b

    就可以了:
    def fib(max):
        n, a, b = 0, 0, 1
        while n < max:
            yield b
            a, b = b, a + b
            n = n + 1
        return 'done'
               
    如果一個函數定義中包含

    yield

    關鍵字,那麼這個函數就不再是一個普通函數,而是一個generator:
    >>> f = fib(6)
    >>> f
    <generator object fib at 0x104feaaa0>
               
    這裡,最難了解的就是generator和函數的執行流程不一樣。函數是順序執行,遇到

    return

    語句或者最後一行函數語句就傳回。而變成generator的函數,在每次調用

    next()

    的時候執行,遇到

    yield

    語句傳回,再次執行時從上次傳回的

    yield

    語句處繼續執行。

    但是用

    for

    循環調用generator時,發現拿不到generator的

    return

    語句的傳回值。如果想要拿到傳回值,必須捕獲

    StopIteration

    錯誤,傳回值包含在

    StopIteration

    value

    中:
    >>> g = fib(6)
    >>> while True:
    ...     try:
    ...         x = next(g)
    ...         print('g:', x)
    ...     except StopIteration as e:
    ...         print('Generator return value:', e.value)
    ...         break
    ...
    g: 1
    g: 1
    g: 2
    g: 3
    g: 5
    g: 8
    Generator return value: done
               

五、疊代器

凡是可作用于

for

循環的對象都是

Iterable

(可疊代的)類型;

凡是可作用于

next()

函數的對象都是

Iterator

(疊代器)類型,它們表示一個惰性計算的序列;

集合資料類型如

list

dict

str

等是

Iterable

但不是

Iterator

,不過可以通過

iter()

函數獲得一個

Iterator

對象。