1. 程式人生 > >廖雪峰--python教程:筆記三

廖雪峰--python教程:筆記三

[1] 小寫 對象 gin collect 內置函數 返回值 python 字典 通過

高級特性:
前面我們簡單的聊了一下Python的數據類型、語句和函數,接下來來聊聊Python的高級特性

切片:
取一個list、tuple、str一部分內容是很常見的操作,而切片操作,可以讓這一個過程變得非常簡單。
對於一個列表集合:
L = [‘student‘,‘teacher‘,‘doctor‘,‘engineer‘]
索引是從0開始,到n-1;所以, L[0] : ‘student‘; L[3] : ‘engineer‘

L[0:2]:表示,取[‘student‘,‘teacher‘],即索引為0,1的值,不包括索引2對應的值

a = L[:]:表示,將變量a指向一個新的賦值的L,並不是L指向的列表對象

L[:2]和L[0:2]是相同的,如果第一個索引為0,則可以省略

L[1:]:表示為[‘teacher‘,‘doctor‘,‘engineer‘],即包括第一個索引1對應的值,同樣的,如果最後一個索引省略,則表示最後一個索引為n(列表的元素個數)

Python還可以對列表元素倒著取:
L[-3:-1]:表示,取[‘teacher‘,‘doctor‘]

還有比較好玩的是,切片還可以跳躍著取元素:
L = list(range(100)),則,L 為 [0,1,...,99]
如:前十個數中,每兩個取一個: L[:10:2],或者對於整個數列L每五個取一個L[::5]

tuple和str字符串也可以像list集合那樣去操作,只不過返回的是tuple和str類型而已。

練習:
利用切片操作,去除字符串的首尾空格,註意不要調用str的strip()方法:

def trim(s):
  ‘‘‘ 首先,判斷輸入字符串,是否為空字符串,若為空,則返回這個字符串;
    若不為空,則進行下一步判斷:
    判斷該字符串是否首尾為空格,如為空格,則遞歸地調用該函數本身
  ‘‘‘
  if len(s)==0:
      return s
  elif s[0] ==  :
      return trim(s[1:])
  elif s[-1] ==  :
      return trim(s[:-1])
  return s

叠代:

對於一個給定的list,tuple,str,dict類型,我們可以通過for...in來循環地取出其元素,這種遍歷,稱其為叠代(Iteration)。因此,我們稱list,tuple,str,dict類型為可叠代對象(Iterable)。那麽,我們怎麽判斷一個對象是否是可叠代對象呢?
方法是,通過collections模塊中的Iterable類型判斷:
isinstance(‘abc‘,Iterable) 返回:True
isinstance是一個內置函數,可以判斷一個對象是否是指定的類型

還可以兩個變量同時叠代,
如:
for x,y in [(1,2),(3,4),(5,6)]:
  print(x,y)

如叠代字典d={‘a‘:1,‘b‘:2,‘c‘:3}
for k,v in d.items():
  print(k,‘=‘.v)
Python 字典(Dictionary) items() 函數以列表返回可遍歷的(鍵, 值) 元組數組。
用法: dict.items()

還可以通過Python的內置函數enumerate()枚舉函數,將列表變成索引-元素對:
L = [‘a‘,‘b‘,‘c‘]
for i,value in enumerate(L):
  print(i,value)
enumerate() 函數用於將一個可遍歷的數據對象(元組或如列表、字符串)組合為一個索引序列,同時列出數據和數據下標,一般用在 for 循環當中
enumerate(sequence, [start=0]):sequence-- 一個序列、叠代器或其他支持叠代對象。start--起始位置

練習:
請使用叠代查找一個list中的最大值和最小值:

def findMinAndMax(L):
    if L == []:
        return (None,None)
    max = min = L[0]
    for i in L:
        if i > max:
        max = i
    elif i < min:
        min = i
    return (min,max)

列表生成器:

這是一個非常好玩且有用的構造列表的好方法,可以取代好多循環,所以,簡單,明了。
如:list(range(100)),[0,...99]

加入for循環在列表中:
[x*x for x in range(5)],[0,1,4,9,16]

加入for循環和if語句判斷在列表中:
[x for x in range(5) if x % 2==0],[0,2,4]

兩個變量和加入兩個for循環在列表中:
[m+n for m in ‘ABC‘ for n in ‘XY‘],[‘AX‘, ‘AY‘, ‘BX‘, ‘BY‘, ‘CX‘, ‘CY‘]

練習:

如果list既包含字符串類型,又包含整數和None,將字符串類型的變為小寫,其他忽略
L = [‘Hello‘,‘World‘,18,‘Apple‘,None]
L2 = [x.lower() for x in L if isinstace(x,str)],[‘hello‘, ‘world‘, ‘apple‘]

生成器:

如果我們使用一個很大的列表的前幾個元素時,我們通過列表生成器來創建這個列表在內存中,是非常浪費內存空間的,再假設,如果這個的列表的元素可以通過某種推算的方法推算出來,那麽,我們是否可以僅僅存這個推算的方法,在取列表元素的時候,通過叠代的操作,一次取一個,而不需要存這個列表的所有元素呢?--Python提供了這個方便,叫做生成器(generator)

生成器,有兩種方法可以構成:
第一種,將列表生成器中的[]換成(),就OK了。
如:g = (x*x for x in range(5)),則L就是一個生成器啦,我們通過next(g)的方式可以從第一個元素取到最後一個元素,當取到最後的元素時,若還調用next(g),則會拋出StopIteration停止叠代的異常,我們並不會這麽傻地使用這種方式取生成器g中的元素,而是通過for循環的方式取(生成器是一個叠代對象),並且這個方式取到g中最後一個元素後,就停止啦,不會有StopIteration異常。

第二種,復雜的生成器,並不是第一種能夠實現了的,所以,我們通過函數來實現。
如,斐波拉契數列1,1,2,3,5,8,13...

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。調用next()函數取fib元素時,在執行時,遇到yield就會中斷,下次又繼續運行。但是,我們都是用for循環來取生成器fib元素的,用for循環調用generator時,拿不到return語句返回的值。如果想要拿到返回值,就必須捕獲StopIteration錯誤,返回值包含在StopIteration的valule中。
如:

g = fib(6)
while True:
    try:
        x = next(g)
        print(g,x)
    except StopIteration as e:
        print(Generator return value:,e.value)
        break    

練習:
楊輝三角:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
...
把每一行當成一個列表,然後寫一個generator,不斷地輸出下一行的list

def triangles(n):
    ‘‘‘
    [1] + [2] + [1] 為: [1,2,1]
    首先,第一個列表L是[1],也就是第一行,然後第接下來的行,由列表生成式構造:
    第二行:
    [1] + [L[i] + L[i+1] for i in range(len(L) -1)] + [1]
    當,range(0)時,想象成循環的話,這是不執行的,也就是[L[i] +     L[i+1] for i in range(len(L)-1)] 是空列表[]。
    第三行:[1] + [L[i] + L[i+1] for i in range(len(L) -1)] + [1]
  ‘‘‘
    L, index = [1], 0
    while index < n:
        yield L
        L = [1] + [L[i] + L[i+1] for i in range(len(L)-1)] + [1]
        index += 1
    return done

for x in triangles(6):
    print(x)

輸出:
[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
[1, 5, 10, 10, 5, 1]

叠代器:

我們知道,用於for循環的類型可以分為兩類:
一是集合類型的: list,tuple,str,dict等
另一類是生成器:列表生成式的生成器和帶yield關鍵字的生成器函數

這些直接作用於for循環的對象,我們稱其為可叠代對象(Iterable),然而生成器不但可以for循環遍歷,還可以通過next()函數取其元素。可以被next()函數調用不斷返回下一個值的對象稱為叠代器:Iterator。

可以把str,list,tuple,dict等Iterable,通過iter()函數變為Iterator
如:
from collections import Iterator
isinstance(iter(‘abc‘),Iterator) -- 返回 True

Python的Iterator對象表示的是一個數據流,Iterator對象可以通過next()函數調用不斷的返回下一個數據,直到沒有數據時,拋出StopIteration錯誤。可以把數據流看作一個有序序列,但我們卻不能提前得知序列的長度,只能不斷通過next()函數實現按需計算下一個數據,因此Iterator的計算是惰性的。
Iterator可以表示一個自然數集合,而list則不能。

實際上,Python中的for循環就是一個不斷通過next()函數實現的:
for x in [1,2,3,4,5]:
  pass

實際上,是這樣實現
it = iter([1,2,3,4,5])
while True:
  try:
    x = next(it)
  except StopIteration:
    break

廖雪峰--python教程:筆記三