1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        20個Python使用小技巧,建議收藏!

        共 5799字,需瀏覽 12分鐘

         ·

        2022-01-12 13:10


        來源丨知乎-張皓

        1. 易混淆操作

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

        1.1 有放回隨機(jī)采樣和無放回隨機(jī)采樣

        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) # 只復(fù)制最頂層
        y = copy.deepcopy(x) # 復(fù)制所有嵌套部分

        復(fù)制和變量別名結(jié)合在一起時,容易混淆:

        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]

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

        1.4 == 和 is

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

        1.5 判斷類型

        type(a) == int      # 忽略面向?qū)ο笤O(shè)計中的多態(tài)特征
        isinstance(a, int) # 考慮了面向?qū)ο笤O(shè)計中的多態(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 后向索引

        這個只是習(xí)慣問題,前向索引時下標(biāo)從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})

        注意,當(dāng) 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) # 當(dāng)predicate為False時停止迭代
        # takewhile(lambda x: x < 5, [1, 4, 6, 4, 1]) -> 1, 4

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

        itertools.compress(iterable, selectors) # 根據(jù)selectors每個元素是True或False進(jìn)行選擇
        # 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) # 當(dāng)最短的序列耗盡時停止,結(jié)果只能被消耗一次
        itertools.zip_longest(*iterables, fillvalue=None) # 當(dāng)最長的序列耗盡時停止,結(jié)果只能被消耗一次

        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)頻次最高的元素和其對應(yīng)出現(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 帶默認(rèn)值的 Dict

        當(dāng)訪問不存在的 Key 時,defaultdict 會將其設(shè)置為某個默認(rèn)值。

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

        2.5 有序 Dict

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

        3. 高性能編程和調(diào)試

        3.1 輸出錯誤和警告信息

        向標(biāo)準(zhǔn)錯誤輸出信息

        import sys
        sys.stderr.write('')

        輸出警告信息

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

        控制警告消息的輸出

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

        3.2 代碼中測試

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

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

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

        $ python -0 main.py

        3.3 代碼風(fēng)格檢查

        使用 pylint 可以進(jìn)行不少的代碼風(fēng)格和語法檢查,能在運行之前發(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)化產(chǎn)生性能瓶頸的地方,而不是全部代碼。
        • 避免使用全局變量。局部變量的查找比全局變量更快,將全局變量的代碼定義在函數(shù)中運行通常會快 15%-30%。
        • 避免使用.訪問屬性。使用 from module import name 會更快,將頻繁訪問的類的成員變量 self.member 放入到一個局部變量中。
        • 盡量使用內(nèi)置數(shù)據(jù)結(jié)構(gòu)。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 轉(zhuǎn)置二維列表

        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))
        瀏覽 43
        點贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

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

        手機(jī)掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            巨大欧美黑人xxxxbbbb | 日本亚洲中文字幕 | 国产精品日韩一区二区三区 | 成人网站 视频免费上海一 | 骚贱烂b调教 | 欧美一区二区三区二区 | 操逼视频免费播放 | 美女操逼逼 | 国产精品国产三级国产aⅴ浪潮 | 偷拍网址 |