python(三)高級特性切片迭代等

切片:取一個list或tuple的部分元素是非常常見的操作

 L = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack']
 ##取前3個元素
 L[0:3]=['Michael', 'Sarah', 'Tracy'] ##或 L=[:3]
 ##N個元素,也就是索引爲0-(N-1)的元素
## 可以從索引1開始,取出2個元素出來:
 >>> L[1:3]
['Sarah', 'Tracy']
##L[-1]取倒數第一個元素,那麼它同樣支持倒數切片,倒數第一個元素是-1 不是從零開始
>>> L[-2:]
['Bob', 'Jack']
>>> L[-2:-1]
['Bob']
##前10個數,每兩個取一個:
>>> L[:10:2]
[0, 2, 4, 6, 8]

迭代 for循環來遍歷這個list或tuple,這種遍歷我們稱爲迭代(Iteration)

for ch in 'ABC':
...     print(ch)
...
A
B
C
###字典 dict 迭代(dict迭代的是key。如果要迭代value,可以用for value in d.values(),如果要同時迭代key和value,可以用for k, v in d.items())
>>> d = {'a': 1, 'b': 2, 'c': 3}
>>> for key in d:
...     print(key)
...
a
c
b

Python內置的enumerate函數可以把一個list變成索引-元素對,這樣就可以在for循環中同時迭代索引和元素本身:

>>> for i, value in enumerate(['A', 'B', 'C']):
...     print(i, value)
...
0 A
1 B
2 C

請使用迭代查找一個list中最小和最大值,並返回一個tuple:

def findMinAndMax(L):
    if L == []:
        return None,None
    # elif len(L) ==1:
    #     max = min = L[0]
    #     return min,max
    else:
        max =L[0]
        min =L[0]
        for i in L:     ### 注意這地方的循環嵌套 要在當前嵌套if裏面 max和min的值纔會生效
            if i > max:
             max = i
        # for i in L:
            if i < min:
                min =i
        return min,max
#####優解
def findMinAndMax(L):
    if not isinstance(L, list):
        raise TypeError('Invalid')
    L_num = [ x for x in L if type(x) is int]  
    if len(L_num) == 0:
        return (None, None)
    min = 0
    max = 0
    for i, value in enumerate(L_num):
        if i == 0:
            min = value
        if value < min:
            min = value
        if value > max:
            max = value
    return (min, max)

列表生成式
用一行語句代替循環生成上面的list

>>> [x * x for x in range(1, 11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
##寫列表生成式時,把要生成的元素x * x放到前面,後面跟for循環 判斷條件 寫到循環後面
>>> [x * x for x in range(1, 11) if x % 2 == 0]
[4, 16, 36, 64, 100]

生成器
受到內存限制,列表容量肯定是有限,列表元素可以按照某種算法推算出來,那我們是否可以在循環的過程中不斷推算出後續的元素,不必創建完整的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>
###generator保存的是算法,每次調用next(g),就計算出g的下一個元素的值,直到計算到最後一個元素,沒有更多的元素時,拋出StopIteration的錯誤。

在比如斐波拉契數列(Fibonacci),除第一個和第二個數外,任意一個數都可由前兩個數相加得到:

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就可以了)
##定義一個generator,依次返回數字1,3,5:
def odd():                      ## 這裏沒有參數變量需要傳入,所以不用命名參數名,每次執行next()函數 生成值
    print('step 1')
    yield 1
    print('step 2')
    yield(3)
    print('step 3')
    yield(5)

練習楊輝三角定義如下:

      1
     / \
    1   1
   / \ / \
  1   2   1
 / \ / \ / \
1   3   3   1

把每一行看做一個list,試寫一個generator,不斷輸出下一行的list:

def triangles():
    L=[1]                               #定義數組並賦初始值
    whiel True:
        yield L                     #生成器每次輸入上次計算的結果 由於yield 返回的原因 會繼續執行下去,並查詢上一次的計算結果
        L1=L[1]                         #每次初始化計算器
        for n in range(1,len(L)):       #循環遍歷上次計算結果
            L1.append(L[n-1]+L[n])      #將上次結果的相鄰兩數相加並賦值
        L1.append(1)                    #末尾加1
        L=L1                            #將計算結果賦值
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章