#3 slice, generator, 列表生成式,可迭代

一.切片

本質(zhì)上就是js中的slice方法,只不過表達(dá)形式上有所不同,一樣的是這是一個純函數(shù)

有以下幾種形式

# 使用 [:] 這種形式表示切片
[startIndex=0:endIndex=len(list)]

# 每隔幾個數(shù)取一個值 [::]
[startIndex=0::numToSkip-1]
# 這種情況當(dāng)為-1時,會反向元素 ?。。?小技巧)

# 取區(qū)域內(nèi)的元素,然后每隔幾個取一個
[startIndex=0:endIndex=len(list):numToSkip-1]

具體示例

# 普通的slice
>>> L = list(range(1, 100, 2)) # 即1-100之間的奇數(shù)組成的list
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 
39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 
73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99]

# 復(fù)制整個list, 直接[:]
>>> anotherList = L[:]

# 復(fù)制部分的list
# 索引為2開始到10(不包含)
>>> partList = L[2:10]
[5, 7, 9, 11, 13, 15, 17, 19]

# 從40開始, 默認(rèn)到最后
>>> partList = L[40:]
[81, 83, 85, 87, 89, 91, 93, 95, 97, 99]

# 默認(rèn)從0開始
>>> partList = L[:10]
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]


# 從后開始 -1為最后一個
>>> partList = L[-5:-1]
[91, 93, 95, 97]
# 后2個數(shù)
>>> partList = L[-2:]
[97, 99]

# 每隔幾個數(shù)取一個
# 每隔(5 - 1) = 4個取一個
>>> L[::5]
[1, 11, 21, 31, 41, 51, 61, 71, 81, 91]

# 前10個每隔1個取一個
>>> L[:10:2]
[1, 5, 9, 13, 17]

>>> L[3:10:2]
[7, 11, 15, 19]

同樣 tuple 類型 和 str 類型也可以使用切片

>>> (1, 2, 3, 4)[:3]
(1, 2, 3)

>>> s = 'ABCDEFG'
>>> s[:3]
'ABC'
>>> s[::2]
'ACEG'

# 取-1時將字符串反向
>>> s[::-1]
'GFEDCBA'

# [::-2] 則是先反向,然后每隔(2-1)個取一個值
>>> s[::-2]
'GECA'

二.迭代

python中對可迭代對象都可以使用 for...in 進(jìn)行迭代操作

如何判斷一個對象是否可迭代,可以使用python提供的 collections 集合中的 'isinstance' 方法,查看是否屬于 Iterable 的實例

from collections import Iterable

# 對字符串str類型
>>> isinstance('abc', Iterable)
True

# 對list類型
>>> isinstance([1, 2, 3], Iterable)
True

# 對字典dict類型
>>> isinstance({'a': 1, 'b': 2}, Iterable)
True

# 對數(shù)值類型
>>> isinstance(123, Iterable)
False

字典dict 迭代

對于字典類型(dict), 可以使用 items(), values() 方法對值或?qū)嶓w進(jìn)行迭代

>>> d = {'a': 1, 'b': 2, 'c': 3}
# 直接對鍵進(jìn)行迭代
# 因為字典是無序的,所以輸出順序不一定
>>> for key in d:
...   print(key)     
a
c
b

# 對值進(jìn)行迭代 values()
>>> for value in d.values():
...   print(value)     
3
2
1

# 對鍵值對進(jìn)行迭代 items()
>>> for k, v in d.items():
...   print(k, '', v)     
'a' 1
'b' 2
'c' 3

list 帶索引迭代

對于list要將索引也顯示出來,則可以使用python內(nèi)置的 enumerate() 函數(shù)將list變?yōu)?索引-值 對

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

0 A
1 B
2 C

字符串str 迭代

>>> for ch in 'ABC':
...   print(ch)
A
B
C

for 循環(huán)同時引用2個變量

python中比較常見

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

1 1
2 4
3 9

三.列表生成式 (list comprehensions)

快速生成一個list的簡寫方式

比如要生成一個這樣的list:

[1*1, 2*2, 3*3, 4*4, ..., 10*10]

一般寫法為:

>>> L = []
>>> for x in range(1, 11):
...   L.append(x * x)

使用列表生成式,可以寫為:

>>> [x * x for x in range(1, 11)]

將要生成的元素 x*x 放在前面, 后面跟著for循環(huán)即可

還可以在for后面添加條件:

# 只對偶數(shù)平方
>>> [x * x for x in range(1, 11) if x % 2 == 0]
[4, 16, 36, 64, 100]

可以添加2層循環(huán)

>>> [m + n for m in 'ABC' for n in 'XYZ']
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']

將dict生成一個list:

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

使用 lower() 方法將列表中的字符串都變?yōu)樾懀?title() 將字符串首字母大寫

>>> L = ['Hello', 18, 'World']
>>> [s.lower() for s in L if isinstance(s, str)]
['hello', 'world']

另外可想而知,轉(zhuǎn)換為大寫的方法為 upper()

四.生成器 generator

好吧,每種語言都是相似的,python中也存在生成器,上面的列表生成式,將'[]' 改為 '()' 即可產(chǎn)生一個generator對象

>>> L = [x * x for x in range(10) if x % 2 == 0]
>>> L
[0, 4, 16, 36, 64]

# 生成一個generator對象
>>> g = (x * x for x in range(10) if x % 2 == 0)
>>> g
<generator object <genexpr> at 0x1022ef630>

生成器的方法 next()

>>> next(g)
0
>>> next(g)
4
>>> next(g)
16
>>> next(g)
36
>>> next(g)
64
>>> next(g)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

當(dāng)然我們可以使用 for 循環(huán)來輸出,不用這么麻煩

>>> for n in g:
...   print(n)
0
4
16
36
64

在函數(shù)中使用 yield 關(guān)鍵詞,創(chuàng)建generator函數(shù),比如斐波拉契數(shù)列:

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

值得注意的是python的這種賦值的語法,十分的簡潔:

n, a, b = 0, 0, 1

# 還有
a, b = b, a + b
# 相當(dāng)于
a = b
b = a + b

調(diào)用函數(shù)生成一個generator對象:

>>> g = fib(6)
>>> g
<generator object fib at 0x104feaaa0>

使用 for 循環(huán)來輸出

>>> for n in g:
...   print(n)

1
1
2
3
5
8

這樣一來就得不到return語句后面的值了(即'done'),如果想要拿到返回值,則必須捕獲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

五.Iterable 和 Iterator

可迭代和迭代器是2個不同的概念,其中:

  • 集合類型的,如 list, dict, str, 都是Iterable的,但不是Iterator, 凡是可作用于for循環(huán)的對象都是Iterable
  • 像generator對象可使用 next() 函數(shù)的都是 Iterator的,同時也是可迭代的Iterable

比如:

from collections import Iterable

# list
>>> isinstance([], Iterable)
True

# dict
>>> isinstance({}, Iterable)
True

# str
>>> isinstance('abc', Iterable)
True

# tuple
>>> isinstance((1, 2, 3), Iterable)
True

# generator
>>> isinstance((x for x in range(10)), Iterable)
True

# 數(shù)值
>>> isinstance(100, Iterable)
False

判斷一個對象是否是 Iterator

from collections import Iterator

>>> isinstance((x for x in range(10)), Iterator)
True
>>> isinstance([], Iterator)
False
>>> isinstance({}, Iterator)
False
>>> isinstance('abc', Iterator)
False

可以使用 iter() 將 list, dict, str 等Iterable變?yōu)?Iterator

>>> isinstance(iter([]), Iterator)
True

>>> isinstance(iter('abc'), Iterator)
True

python中將Iterator對象表示為一個數(shù)據(jù)流,Iterator對象可以被next()函數(shù)調(diào)用并不斷的返回下一個數(shù)據(jù),直到?jīng)]有數(shù)據(jù)拋出 StopIteration 錯誤, Iterator的計算是 惰性的, 可以表示一個無限大的數(shù)據(jù)流

總結(jié)

本章主要將的是一些常用的數(shù)據(jù)操作:

  • 切片,和js中的slice類似,只是寫法不同,還有就是可以隔幾個選取1個,稍微有點差異
  • 迭代,對集合類型的數(shù)據(jù)進(jìn)行for...in循環(huán), 字典中存在 'values()', 'items()' 等方法, list如果想使用索引,可以使用內(nèi)置的 enumerate() 函數(shù)
  • 列表生成式,快速生成一個list的簡便寫法,可以寫二維或以上的for循環(huán),還可以添加條件判斷
  • 生成器,這個用來對函數(shù)進(jìn)行控制,快速生成生成器對象的方式和列表生成式比較類似
  • 可迭代和迭代器的區(qū)別,以及使用 iter() 將可迭代轉(zhuǎn)換為迭代器
  • 異常捕獲使用 try...except ExceptType
  • 另外接觸到的函數(shù) lower(), upper(), title()

2017年3月5日 21:55:26

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容