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>

        53個技巧!老司機(jī)熬夜總結(jié)Python 使用和高性能技巧大集合!

        共 7819字,需瀏覽 16分鐘

         ·

        2022-01-09 18:07

        張皓?https://zhuanlan.zhihu.com/p/4829346


        下面是老司機(jī)總結(jié)的一些干貨技巧,非常有價值,尤其是對比c/c++有其他語言編程基礎(chǔ)的小伙伴,記得收藏哦!


        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. C/C++ 用戶使用指南

        不少 Python 的用戶是從以前 C/C++ 遷移過來的,這兩種語言在語法、代碼風(fēng)格等方面有些不同,本節(jié)簡要進(jìn)行介紹。

        2.1 很大的數(shù)和很小的數(shù)

        C/C++ 的習(xí)慣是定義一個很大的數(shù)字,Python 中有 inf 和 -inf:

        a = float('inf')
        b = float('-inf')

        2.2 布爾值

        C/C++ 的習(xí)慣是使用 0 和非 0 值表示 True 和 False, Python 建議直接使用 True 和 False 表示布爾值。

        a = True
        b = False

        2.3 判斷為空

        C/C++ 對空指針判斷的習(xí)慣是 if (a) 和 if (!a)。Python 對于 None 的判斷是:

        if x is None:
        pass

        如果使用 if not x,則會將其他的對象(比如長度為 0 的字符串、列表、元組、字典等)都會被當(dāng)做 False。

        2.4 交換值

        C/C++ 的習(xí)慣是定義一個臨時變量,用來交換值。利用 Python 的 Tuple 操作,可以一步到位。

        a, b = b, a

        2.5 比較

        C/C++ 的習(xí)慣是用兩個條件。利用 Python 可以一步到位。

        if 0 < a < 5:
        pass

        2.6 類成員的 Set 和 Get

        C/C++ 的習(xí)慣是把類成員設(shè)為 private,通過一系列的 Set 和 Get 函數(shù)存取其中的值。在 Python 中雖然也可以通過 @property、@setter、@deleter 設(shè)置對應(yīng)的 Set 和 Get 函數(shù),我們應(yīng)避免不必要的抽象,這會比直接訪問慢 4 - 5 倍。

        2.7 函數(shù)的輸入輸出參數(shù)

        C/C++ 的習(xí)慣是把輸入輸出參數(shù)都列為函數(shù)的參數(shù),通過指針改變輸出參數(shù)的值,函數(shù)的返回值是執(zhí)行狀態(tài),函數(shù)調(diào)用方對返回值進(jìn)行檢查,判斷是否成功執(zhí)行。在 Python 中,不需要函數(shù)調(diào)用方進(jìn)行返回值檢查,函數(shù)中遇到特殊情況,直接拋出一個異常。

        2.8 讀文件

        相比 C/C++,Python 讀文件要簡單很多,打開后的文件是一個可迭代對象,每次返回一行內(nèi)容。

        with open(file_path, 'rt', encoding='utf-8') as f:
        for line in f:
        print(line) # 末尾的\n會保留

        2.9 文件路徑拼接

        C/C++ 的習(xí)慣通常直接用 + 將路徑拼接,這很容易出錯,Python 中的 os.path.join 會自動根據(jù)操作系統(tǒng)不同補充路徑之間的 / 或 \ 分隔符:

        import os
        os.path.join('usr', 'lib', 'local')

        2.10 解析命令行選項

        雖然 Python 中也可以像 C/C++ 一樣使用 sys.argv 直接解析命令行選擇,但是使用 argparse 下的 ArgumentParser 工具更加方便,功能更加強大。

        2.11 調(diào)用外部命令

        雖然 Python 中也可以像 C/C++ 一樣使用 os.system 直接調(diào)用外部命令,但是使用 subprocess.check_output 可以自由選擇是否執(zhí)行 Shell,也可以獲得外部命令執(zhí)行結(jié)果。

        import subprocess
        # 如果外部命令返回值非0,則拋出subprocess.CalledProcessError異常
        result = subprocess.check_output(['cmd', 'arg1', 'arg2']).decode('utf-8')
        # 同時收集標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯誤
        result = subprocess.check_output(['cmd', 'arg1', 'arg2'], stderr=subprocess.STDOUT).decode('utf-8')
        # 執(zhí)行shell命令(管道、重定向等),可以使用shlex.quote()將參數(shù)雙引號引起來
        result = subprocess.check_output('grep python | wc > out', shell=True).decode('utf-8')

        2.12 不重復(fù)造輪子

        不要重復(fù)造輪子,Python稱為batteries included即是指Python提供了許多常見問題的解決方案。

        3. 常用工具

        3.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')

        3.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é)果只能被消耗一次

        3.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)

        3.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]提供一個初始值

        3.5 有序 Dict

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

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

        4.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')

        4.2 代碼中測試

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

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

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

        $ python -0 main.py

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

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

        pylint main.py

        4.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=':') 低。

        5. Python 其他技巧

        5.1 argmin 和 argmax

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

        argmax同理。

        5.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

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

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

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


        (完)

        點「在看」的人都變好看了哦
        瀏覽 48
        點贊
        評論
        收藏
        分享

        手機(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>
            中文字幕不卡AV在线观看| 欧美国产性爱| jzzijzzij亚洲成熟少妇在线观看 九色蝌蚪9l视频蝌蚪9l视频成人熟妇 | A级免费视频| 日韩无码乱码| 亚洲午夜AV| 亚州AV天堂| 成人在线乱码视频| 亚洲影音| 久久99深爱久久99精品| 狠狠穞A片一區二區三區| 狠狠操在线观看| 婷婷激情av| 精品亚洲一区二区三区四区五区| 豆花视频免费| 大肉大捧一进一出免费阅读| 中文字幕天天在线| A片欧美| 久久久久久久毛片| 淫荡五月天视频导航| 亚洲网站在线观看| 在线中文字幕网站| 蜜桃视频无码| 国模吧一区| 肏屄视频在线| 在线天堂av| 欧美一区二区三区成人片在线| 国产内射网站| 高清无码在线免费观看视频| 91香蕉视频免费| 九九九九九九精品视频| 婷婷五月亚洲精品AAA片在| 国产一级黄色A片| 日韩五月婷婷| 国产麻豆精品ThePorn| 日韩无码人妻一区二区三区| 精品人妻一区二区三区四区不卡在 | 久久精品小视频| 色婷婷狠狠| 在线看黄网站| 黄色A片在线观看| 国产操比视频| 欧美精品成人免码在线| A片免费在线播放| 久久五月丁香| 婷婷久久网| 日韩在线播放视频| 俺来也在线视频| 成人精品一区二区区别解析| 亚洲精品午夜| 日本精品黄色| 欧洲美一区二区三区亚洲| 成人精品123| 国产手机拍视频推荐2023| 国产美女精品视频| 肏逼综合网| 特级西西444www无码视频免费看 | 精品一区国产探花| 日韩在线一区二区三区| 亚洲精品无码视频| 露脸偷拍AV2025| 亚洲AV在线人妻| 91国产做爱| 91国黄色毛片在线观看| 骚逼视频聊天记录| 欧美日韩国产尤物主播精品| 欧美操B电影| 欧美激情伊人久久五月天| 初学影院WWWBD英语完整版在线观看| 亚洲色图15p| 韩国精精品视频| 日本人人操人人摸| 国产亚洲欧美一区二区| 免费一级婬片AA片观看| 丝袜足交视频在线观看| 91在线无码精品秘网站| 亚洲国产成人精品午夜| 韩国一区二区三区在线观看| 欧美A片在线免费观看| 92自拍视频| 一区二区三区高清不卡| 在线欧美日| 在线播放一区二区三区| chinese高潮老女人| 久久久久久久免费无码| 三级大香蕉| 午夜无码三级| 色乱视频| 国产美女高潮视频| 五月婷婷性爱| 日本乱伦网站| 人妖无码| 婷婷丁香六月天| 日韩人妻无码一区二区三区99 | 欧美一页| 黄色国产av| 99热66| 中文字幕偷拍| 婷婷五月天中文字幕| 国内精品国产成人国产三级| 久久久婷婷| 一级a片激情啪啪免费观| 做爱视频网站18| 欧美成人一区二区三区片| 青草香蕉视频| 粉嫩99国产精品久久久久久人妻| 国产日B| 97视频精品| 激情五月激情综合网| 日韩一级免费电影| 蜜臀久久99精品久久久兰草影视| 91丝袜| 日韩人妻在线观看| 精品AV| 色网在线观看| 四虎最新视频| 久久911| 无码人妻免费视频| 精品AAA| 日本国产视频| 久草视频免费看| 97人妻无码| 日韩综合另类| 熟女人妻人妻HD| 丁香激情五月天| av拍拍| 日韩AV毛| 国产精品一区二区AV日韩在线| 国产又爽又黄视频| 中文字幕五码| 日韩无码五月天| 香蕉视频亚洲| 亚洲视频二区| 俺也操| 成人AV在线电影| 亚洲色图一区二区| 西西人体444www| 欧美日韩久久久| 亚洲中文字幕免费在线观看| 午夜精品电影| 欧美成人大香蕉| 国精产品一区二区三区| 黑人粗暴偷拍一区二区| 西西444WWW无码视频软件| 特黄色A级片视频| 伊大香蕉| 欧美性BBB槡BBB槡BBB| 久久久成人免费电影| 伊人99热| 精品视频在线观看| 男女性爱视频免费| 欧美精品一级| 777大香蕉| 青青草中文字幕| 国产成人三级片| 欧美精品99| 九九r在线精品观看视频| 亚洲无码在线高清| 三级片无码在线| 亚洲精品免费在线观看| 亚洲AV无码成人精品区大猫| 亚洲精品大片| 在线观看国产| 91精品国产闺蜜国产在线闺蜜| 青青久久91| 国产精品每日更新| 又黄又爽无遮挡| 黃色一级A一片人与| 一级A片免费看| 11孩岁女精品A片BBB| 高清在线无码视频| 四川BBB嫩BBBB爽BBBB| 自拍偷拍精品| 丁香av| 国产三级片网站| 午夜三级视频| 久久亚洲精品视频| 无码无码无码| 日韩欧美小视频| 国产A片免费看| 国产精品18进进出出17c| 影音先锋婷婷| 麻豆精品无码| 99热er| 日韩视频一区二区三区| 日韩视频免费观看高清完整版在线观 | 日韩一区二区免费视频| 高清无码在线观看视频| 日韩欧美在线中文| 在线观看不卡av| 国产区在线| 亚洲精品国产成人综合久久久久久久久| 国产秘久久一区二区| 欧美午夜精品一区二区蜜桃| 五月一区| 综合偷拍| 久久久亚洲熟妇熟女| 午夜福利无码视频| 亚洲色情在线播放| 国产欧美日韩在线播放| 大茄子熟女AV导航| www.91自拍| 国产欧美高清在线| 久久五月天综合| 国产美女一级真毛片酒店| 嫩草在线视频| 无码视频在线观看| 香蕉中文网| 欧美日韩无码视频| 777免费视频| 日韩AV在线免费观看| 国产特级毛片AAAAAA| 三级黄色免费网站| 日韩欧美内射| 青娱乐青青草| 中文字幕无吗| 亚洲色色色| 99热都是精品| 一区二区三区四区在线| 成人一区二区三区四区五区| 成人欧美精品| 一级a一级a爱片免费视频| 男女拍拍视频| 97人操| 丰满人妻一区二区三区免费| 无码福利电影| 日本高清视频网站网wwwwww| a免费视频在线观看| 一本色道久久综合无码人妻软件 | 亚洲丝袜av| 91久久国产综合久久91精品网站 | 青青热视频| 日韩性爱av| 免费的毛片| 成人视频网站18| 91AV天天在线观看| 免费日韩毛片| 国产性生活| 亚洲va综合va国产va中文| 九月丁香婷婷| 天天色天天爱| 国产成人高清| 国产午夜三级| 人人操人人搞| 日韩成人无码视频| 日韩一级性爱| 囯产一级a一级a免费视频| 亚洲精品成人7777777| 精品九九九| 精品一区二区免费视频| 玖玖99视频| 欧美日韩黄片| 成人动漫免费观看| 毛片精品| 综合天堂AV久久久久久久| 国产一区视频在线| 久久婷婷成人综合色怡春院| 91狠狠| 香蕉av在线播放| 日韩精品A片| 丁香婷婷一区二区三区| 2015中文字幕黄色视频| 少妇做爱特级AAA| 日韩精品一级| 91视频在线观看| 人人爱人人操人人干| 欧美亚洲一区二区三区| 日韩一级片在线观看| 欧美a片在线看| 色婷婷一区二区三区久久午夜| 欧美黄色网| 夜夜操天天| 毛片毛片毛片毛片毛片| 黄色福利视频| 狠狠干2022| 99热播| 91成人片| 你懂得视频| 福利导航在线| 伊人久久狼人| 69成人在线电影| 亚洲熟女一区| 波多野结衣无码流出| 国产aaaaaa| 国产无码成人免费| 久久久免费黄色视频| 九九综合网| 激情在线视频| 五月丁香色色网| 91福利视频网站| 精品人妻一区二区三区鲁大师| 大香蕉久久精品| 日韩中文字幕在线观看视频| 操一操| 亚洲91成人| 高清无码在线免费| 插菊花综合网亚洲| 国产精品揄拍100视频| 夜夜躁狠狠躁日日躁av| 免费无码国产在线怀|