1. 程式人生 > 其它 >Effective Python學習筆記(一)

Effective Python學習筆記(一)

技術標籤:Effective Python學習筆記python生成器列表

part 1. 用Pythonic的方式思考

  1. 確認自己所用的python版本(使用python3.x)

  2. 遵循PEP8風格指南

    • 使用space來表示縮排,而不要使用tab,和語法相關的每一層縮排都用4個空格來表示
    • 其他的PEP8風格標準可以通過Pycharm自帶的風格修正來完成(Reformat File)
    • 函式、變數以及屬性應該用小寫字母來拼寫,各單詞之間用下劃線連線,如:lowercase_underscore
    • 受保護的例項屬性應該以單個下劃線開頭,如:_leading_underscore
    • 私有的例項屬性應該以兩個下劃線開頭,如__double_leading_underscore
    • 類與異常應該以每個單詞首字母大寫的形式命名,如GradeBook
    • 模組級別的常量應該全部採用大寫字母拼寫,各單詞之間用下劃線連線,如ALL_CAPS
  3. bytes、str、unicode的區別

    • 編寫python程式時,要把編碼和解碼工作放在介面的最外圍來做

    • #接受str或bytes,返回str
      def to_str(bytes_or_str):
          if isintance(bytes_or_str, bytes):
              value = bytes_or_str.decode('utf8')
          else:
              value = bytes_or_str
          return
      value #接受str或bytes,返回bytes def to_bytes(bytes_or_str): if isinstance(bytes_or_str): value = bytes_or_str.encode('utf8') else: value = bytes_or_str return value
    • 用’wb’或’rb’來以二進位制格式來開啟並讀寫檔案

  4. 用輔助函式來取代複雜的表示式

    • 將複雜的表示式移入輔助函式之中,特別是在要反覆使用同樣的邏輯的時候
    • 使用if/else表示式要比用or/and這樣的布林操作符寫成的表示式更加清晰
  5. 切割序列的方法

    • 切割格式:[start​ : end : ​stride]
    • start為開始索引,涵蓋在切割後的範圍中;end為結束索引,所指的元素不包含在切割結果中
    • 切割列表時,即使start或end索引越界也不會出現問題,但訪問列表中的單個元素時下標越界會導致異常
  6. 在單詞切片操作內,不要同時指定start、end和stride

  7. 用列表推導來取代map和filter

    • a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
      squares = [x**2 for x in a]
      print(squares)
      #輸出[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
      
    • 使用map需要建立lambda函式,以便計算新列表中各個元素的值

    • 列表推導可以跳過輸入列表中的某些元素,如果改用map來做,那就必須輔以filter才能實現

  8. 不要使用含有兩個以上表達式的列表推導

    • 列表推導支援多級迴圈,每一級迴圈也支援多項條件,但超過兩個表示式的列表推導是很難理解的,應該儘量避免
  9. 用生成器表示式來改寫資料量大的列表推導

    • 列表推導在推導的過程中,對於輸入序列中的每個值來說可能都要建立僅含一項元素的全新列表,輸入資料較多的時候可能會因為消耗大量記憶體引起程式崩潰

    • 生成器表示式在執行的時候並不會把整個輸出序列都呈現出來,而是會估值為迭代器,每個迭代器每次可以根據生成器表示式產生一項資料。對生成器求值時,它會立刻返回一個迭代器而不會深入處理檔案中的內容

    • #列表推導式
      value = [len(x) for x in open('test.txt')]
      print(value)
      
      #生成器表示式
      it = (len(x) for x in open('test.txt'))
      print(next(it))
      
  10. 儘量使用enumerate取代range

    • python提供了內建的enumerate函式,可以把各種迭代器包裝為生成器,以便稍後產生輸出值。生成器每次產生一對輸出值,其中前者表達迴圈下標,後者表示從迭代器中獲取到的下一個序列元素

    • for i, flavor in enumerate(flavoe_list):
      	print('%d: %s' % (i + 1, flavor))
      
  11. 用zip函式同時遍歷兩個迭代器

    • for name, count in zip(names, letters):
      	if count > max_letters:
      		longest_name = name
      		max_letters = count
      
    • 受封裝的迭代器中只要有一個耗盡,zip就不再產生新元組。若不能確定zip所封裝的列表是否等長,則可以使用itertools內建模組中的zip_longest函式

  12. 不要在for和while迴圈後面寫else塊(一般不會這麼寫吧)

  13. 合理利用try/except/else/finally結構中的每個程式碼塊

    • finally塊(常見用途:確保關閉檔案控制代碼):

      handle = open('test.txt')
      try:
      	data = handle.read()
      finally:
      	handle.close() #檔案成功開啟則一定能執行
      
    • else塊:

      def load_json_key(data, key):
      	try:
      		result_dict = json.loads(data)
      	except ValueError as e:
      		raise KeyError from e
      	else:
      		return result_dict[key]