<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          干貨!20個Python使用小技巧

          共 6033字,需瀏覽 13分鐘

           ·

          2022-01-06 19:26

          來源:知乎-張皓

          1. 易混淆操作

          本節(jié)對一些 Python 易混淆的操作進行對比。

          1.1 有放回隨機采樣和無放回隨機采樣

          import random
          random.choices(seq, k=1) # 長度為k的list,有放回采樣
          random.sample(seq, k) # 長度為k的list,無放回采樣

          1.2 lambda 函數(shù)的參數(shù)

          func = lambda y: x + y          # x的值在函數(shù)運行時被綁定
          func = lambda y, x=x: x + y # x的值在函數(shù)定義時被綁定

          1.3 copy 和 deepcopy

          import copy
          y = copy.copy(x) # 只復制最頂層
          y = copy.deepcopy(x) # 復制所有嵌套部分

          復制和變量別名結合在一起時,容易混淆:

          a = [1, 2, [3, 4]]

          # Alias.
          b_alias = a
          assert b_alias == a and b_alias is a

          # Shallow copy.
          b_shallow_copy = a[:]
          assert b_shallow_copy == a and b_shallow_copy is not a and b_shallow_copy[2] is a[2]

          # Deep copy.
          import copy
          b_deep_copy = copy.deepcopy(a)
          assert b_deep_copy == a and b_deep_copy is not a and b_deep_copy[2] is not a[2]

          對別名的修改會影響原變量,(淺)復制中的元素是原列表中元素的別名,而深層復制是遞歸的進行復制,對深層復制的修改不影響原變量。

          1.4 == 和 is

          x == y  # 兩引用對象是否有相同值
          x is y # 兩引用是否指向同一對象

          1.5 判斷類型

          type(a) == int      # 忽略面向對象設計中的多態(tài)特征
          isinstance(a, int) # 考慮了面向對象設計中的多態(tài)特征

          1.6 字符串搜索

          str.find(sub, start=None, end=None); str.rfind(...)     # 如果找不到返回-1
          str.index(sub, start=None, end=None); str.rindex(...) # 如果找不到拋出ValueError異常

          1.7 List 后向索引

          這個只是習慣問題,前向索引時下標從0開始,如果反向索引也想從0開始可以使用~。

          print(a[-1], a[-2], a[-3])
          print(a[~0], a[~1], a[~2])


          2. 常用工具

          2.1 讀寫 CSV 文件

          import csv
          # 無header的讀寫
          with open(name, 'rt', encoding='utf-8', newline='') as f: # newline=''讓Python不將換行統(tǒng)一處理
          for row in csv.reader(f):
          print(row[0], row[1]) # CSV讀到的數(shù)據(jù)都是str類型
          with open(name, mode='wt') as f:
          f_csv = csv.writer(f)
          f_csv.writerow(['symbol', 'change'])

          # 有header的讀寫
          with open(name, mode='rt', newline='') as f:
          for row in csv.DictReader(f):
          print(row['symbol'], row['change'])
          with open(name, mode='wt') as f:
          header = ['symbol', 'change']
          f_csv = csv.DictWriter(f, header)
          f_csv.writeheader()
          f_csv.writerow({'symbol': xx, 'change': xx})

          注意,當 CSV 文件過大時會報錯:_csv.Error: field larger than field limit (131072),通過修改上限解決

          import sys
          csv.field_size_limit(sys.maxsize)

          csv 還可以讀以 \t 分割的數(shù)據(jù)

          f = csv.reader(f, delimiter='\t')

          2.2 迭代器工具

          itertools 中定義了很多迭代器工具,例如子序列工具:

          import itertools
          itertools.islice(iterable, start=None, stop, step=None)
          # islice('ABCDEF', 2, None) -> C, D, E, F

          itertools.filterfalse(predicate, iterable) # 過濾掉predicate為False的元素
          # filterfalse(lambda x: x < 5, [1, 4, 6, 4, 1]) -> 6

          itertools.takewhile(predicate, iterable) # 當predicate為False時停止迭代
          # takewhile(lambda x: x < 5, [1, 4, 6, 4, 1]) -> 1, 4

          itertools.dropwhile(predicate, iterable) # 當predicate為False時開始迭代
          # dropwhile(lambda x: x < 5, [1, 4, 6, 4, 1]) -> 6, 4, 1

          itertools.compress(iterable, selectors) # 根據(jù)selectors每個元素是True或False進行選擇
          # compress('ABCDEF', [1, 0, 1, 0, 1, 1]) -> A, C, E, F

          序列排序:

          sorted(iterable, key=None, reverse=False)

          itertools.groupby(iterable, key=None) # 按值分組,iterable需要先被排序
          # groupby(sorted([1, 4, 6, 4, 1])) -> (1, iter1), (4, iter4), (6, iter6)

          itertools.permutations(iterable, r=None) # 排列,返回值是Tuple
          # permutations('ABCD', 2) -> AB, AC, AD, BA, BC, BD, CA, CB, CD, DA, DB, DC

          itertools.combinations(iterable, r=None) # 組合,返回值是Tuple
          itertools.combinations_with_replacement(...)
          # combinations('ABCD', 2) -> AB, AC, AD, BC, BD, CD

          多個序列合并:

          itertools.chain(*iterables)                        # 多個序列直接拼接
          # chain('ABC', 'DEF') -> A, B, C, D, E, F

          import heapq
          heapq.merge(*iterables, key=None, reverse=False) # 多個序列按順序拼接
          # merge('ABF', 'CDE') -> A, B, C, D, E, F

          zip(*iterables) # 當最短的序列耗盡時停止,結果只能被消耗一次
          itertools.zip_longest(*iterables, fillvalue=None) # 當最長的序列耗盡時停止,結果只能被消耗一次

          2.3 計數(shù)器

          計數(shù)器可以統(tǒng)計一個可迭代對象中每個元素出現(xiàn)的次數(shù)。

          import collections
          # 創(chuàng)建
          collections.Counter(iterable)

          # 頻次
          collections.Counter[key] # key出現(xiàn)頻次
          # 返回n個出現(xiàn)頻次最高的元素和其對應出現(xiàn)頻次,如果n為None,返回所有元素
          collections.Counter.most_common(n=None)

          # 插入/更新
          collections.Counter.update(iterable)
          counter1 + counter2; counter1 - counter2 # counter加減

          # 檢查兩個字符串的組成元素是否相同
          collections.Counter(list1) == collections.Counter(list2)

          2.4 帶默認值的 Dict

          當訪問不存在的 Key 時,defaultdict 會將其設置為某個默認值。

          import collections
          collections.defaultdict(type) # 當?shù)谝淮卧L問dict[key]時,會無參數(shù)調用type,給dict[key]提供一個初始值

          2.5 有序 Dict

          import collections
          collections.OrderedDict(items=None) # 迭代時保留原始插入順序

          3. 高性能編程和調試

          3.1 輸出錯誤和警告信息

          向標準錯誤輸出信息

          import sys
          sys.stderr.write('')

          輸出警告信息

          import warnings
          warnings.warn(message, category=UserWarning)
          # category的取值有DeprecationWarning, SyntaxWarning, RuntimeWarning, ResourceWarning, FutureWarning

          控制警告消息的輸出

          $ python -W all     # 輸出所有警告,等同于設置warnings.simplefilter('always')
          $ python -W ignore # 忽略所有警告,等同于設置warnings.simplefilter('ignore')
          $ python -W error # 將所有警告轉換為異常,等同于設置warnings.simplefilter('error')

          3.2 代碼中測試

          有時為了調試,我們想在代碼中加一些代碼,通常是一些 print 語句,可以寫為:

          # 在代碼中的debug部分
          if __debug__:
          pass

          一旦調試結束,通過在命令行執(zhí)行 -O 選項,會忽略這部分代碼:

          $ python -0 main.py

          3.3 代碼風格檢查

          使用 pylint 可以進行不少的代碼風格和語法檢查,能在運行之前發(fā)現(xiàn)一些錯誤

          pylint main.py

          3.4 代碼耗時

          耗時測試

          $ python -m cProfile main.py

          測試某代碼塊耗時

          # 代碼塊耗時定義
          from contextlib import contextmanager
          from time import perf_counter

          @contextmanager
          def timeblock(label):
          tic = perf_counter()
          try:
          yield
          finally:
          toc = perf_counter()
          print('%s : %s' % (label, toc - tic))

          # 代碼塊耗時測試
          with timeblock('counting'):
          pass

          代碼耗時優(yōu)化的一些原則

          • 專注于優(yōu)化產生性能瓶頸的地方,而不是全部代碼。
          • 避免使用全局變量。局部變量的查找比全局變量更快,將全局變量的代碼定義在函數(shù)中運行通常會快 15%-30%。
          • 避免使用.訪問屬性。使用 from module import name 會更快,將頻繁訪問的類的成員變量 self.member 放入到一個局部變量中。
          • 盡量使用內置數(shù)據(jù)結構。str, list, set, dict 等使用 C 實現(xiàn),運行起來很快。
          • 避免創(chuàng)建沒有必要的中間變量,和 copy.deepcopy()。
          • 字符串拼接,例如 a + ':' + b + ':' + c 會創(chuàng)造大量無用的中間變量,':',join([a, b, c]) 效率會高不少。另外需要考慮字符串拼接是否必要,例如 print(':'.join([a, b, c])) 效率比 print(a, b, c, sep=':') 低。

          4. Python 其他技巧

          4.1 argmin 和 argmax

          items = [2, 1, 3, 4]
          argmin = min(range(len(items)), key=items.__getitem__)

          argmax同理。

          4.2 轉置二維列表

          A = [['a11', 'a12'], ['a21', 'a22'], ['a31', 'a32']]
          A_transpose = list(zip(*A)) # list of tuple
          A_transpose = list(list(col) for col in zip(*A)) # list of list

          4.3 一維列表展開為二維列表

          A = [1, 2, 3, 4, 5, 6]

          # Preferred.
          list(zip(*[iter(A)] * 2))








          加入知識星球【我們談論數(shù)據(jù)科學】

          500+小伙伴一起學習!








          ·?推薦閱讀?·

          「Python實用秘技01」復雜zip文件的解壓

          「Python實用秘技02」給Python函數(shù)定“鬧鐘”

          「Python實用秘技03」導出項目的極簡環(huán)境依賴



          瀏覽 45
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  91人人爽 | 日韩三级国产 | 清纯粉嫩极品夜夜嗨AV | 欧美成年人在线视频 | 亚洲婷婷六月天 |