1. 程式人生 > >【Python】pythonnic用法總結

【Python】pythonnic用法總結

使用生成器 yield

生成器是 python 裡面一個非常有用的語法特性,卻也是最容易被忽視的一個,可能是因為大部分能用生成器的地方也能用列表吧。

生成器可以簡單理解成一個函式,每次執行到 yield 語句就返回一個值,通過不停地呼叫這個函式,就能獲取到所有的值,這些值就能構成了一個等效的列表,但是與列表不同的是,這些值是不斷計算得出,而列表是在一開始就計算好了,這就是 lazy evaluation 的思想。這個特性在資料量特別大的場景非常有用,比如大資料處理,一次無法載入所有的檔案,使用生成器就能做到一行一行處理,而不用擔心記憶體溢位

 

1

2

3

4

5

6

7

8

9

10

def fibonacci():

 num0 = 0

 num1 = 1

 for i in range(10):

  num2 = num0 + num1

  yield num2

  num0 = num1

  num1 = num2

for i in fibonacci():

 print(i)

用 else 子句簡化迴圈和異常

if / else 大家都用過,但是在 python 裡面,else 還可以用在迴圈和異常裡面

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

# pythonic 寫法

for cc in ['UK', 'ID', 'JP', 'US']:

 if cc == 'CN':

  break

else:

 print('no CN')

# 一般寫法

no_cn = True

for cc in ['UK', 'ID', 'JP', 'US']:

 if cc == 'CN':

  no_cn = False

  break

if no_cn:

 print('no CN')

else 放在迴圈裡面的含義是,如果迴圈全部遍歷完成,沒有執行 break,則執行 else 子句

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

# pythonic 寫法

try:

 db.execute('UPDATE table SET xx=xx WHERE yy=yy')

except DBError:

 db.rollback()

else:

 db.commit()

# 一般寫法

has_error = False

try:

 db.execute('UPDATE table SET xx=xx WHERE yy=yy')

except DBError:

 db.rollback()

 has_error = True

if not has_error:

 db.commit()

else 放到異常裡面可以表示,如果沒有異常發生需要執行的操作

用 with 子句自動管理資源

我們都知道,開啟的檔案需要在用完之後關閉,要不就會造成資源洩露,但是實際程式設計的時候經常會忘記關閉,特別是在一些邏輯複雜的場景中,更是如此,python 有一個優雅地解決方案,那就是 with 子句

 

1

2

3

4

5

6

7

8

9

# pythonic 寫法

with open('pythonic.py') as fp:

 for line in fp:

  print(line[:-1])

# 一般寫法

fp = open('pythonic.py')

for line in fp:

 print(line[:-1])

fp.close()

使用 with as 語句後,無需手動呼叫 fp.close() , 在作用域結束後,檔案會被自動 close 掉,完整的執行過如下:

  • 呼叫 open('pythonic.py') ,返回的一個物件 obj,
  • 呼叫 obj.__enter__() 方法,返回的值賦給 fp
  • 執行 with 中的程式碼塊
  • 執行 obj.__exit__()
  • 如果這個過程發生異常,將異常傳給 obj.__exit__() ,如果 obj.__exit__() 返回 False, 異常將被繼續丟擲,如果返回 True,異常被掛起,程式繼續執行

列表推導與生成器表示式

列表推導

[expr for iter_var in iterable if cond_expr]

生成器表示式

(expr for iter_var in iterable if cond_expr)

列表推導和生成器表示式提供了一種非常簡潔高效的方式來建立列表或者迭代器

 

1

2

3

4

5

6

# pythonic 寫法

squares = [x * x for x in range(10)]

# 一般寫法

squares = []

for x in range(10):

 squares.append(x * x)

用 items 遍歷 map

python 裡面 map 的遍歷有很多種方式,在需要同事使用 key 和 value 的場合,建議使用 items() 函式

 

1

2

3

4

5

m = {'one': 1, 'two': 2, 'three': 3}

for k, v in m.items():

 print(k, v)

for k, v in sorted(m.items()):

 print(k, v)