您好,登錄后才能下訂單哦!
這篇文章主要介紹了python使用數(shù)字與字符串方法技巧有哪些,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
下面的代碼使用數(shù)字來作為判斷條件的語句,如果你從別人手里接手過這部分代碼,很難第一時(shí)間理解它的意義。
def mark_trip_as_featured(trip): """將某個(gè)旅程添加到推薦欄目 """ if trip.source == 11: do_some_thing(trip) elif trip.source == 12: do_some_other_thing(trip) ... ... return
我們可以使用枚舉的方式,對這些數(shù)字部分做一些說明。
from enum import IntEnum class TripSource(IntEnum): FROM_WEBSITE = 11 FROM_IOS_CLIENT = 12 def mark_trip_as_featured(trip): if trip.source == TripSource.FROM_WEBSITE: do_some_thing(trip) elif trip.source == TripSource.FROM_IOS_CLIENT: do_some_other_thing(trip) ... ... return
將重復(fù)出現(xiàn)的數(shù)字定義成枚舉類型,不僅改善了代碼的可讀性,還降低了代碼出現(xiàn) Bug
的機(jī)率。
當(dāng)然不是所有的數(shù)字都需要用到枚舉說明,像常見數(shù)字下標(biāo) 0 和 -1
就不需要。
“ 裸字符串處理 ” 這里指只使用基本的加減乘除和循環(huán)、配合內(nèi)置函數(shù)/方法來操作字符串,獲得我們需要的結(jié)果。
def fetch_users(conn, min_level=None, gender=None, has_membership=False, sort_field="created"): """獲取用戶列表 :param int min_level: 要求的最低用戶級(jí)別,默認(rèn)為所有級(jí)別 :param int gender: 篩選用戶性別,默認(rèn)為所有性別 :param int has_membership: 篩選所有會(huì)員/非會(huì)員用戶,默認(rèn)非會(huì)員 :param str sort_field: 排序字段,默認(rèn)為按 created "用戶創(chuàng)建日期" :returns: 列表:[(User ID, User Name), ...] """ # 一種古老的 SQL 拼接技巧,使用 "WHERE 1=1" 來簡化字符串拼接操作 # 區(qū)分查詢 params 來避免 SQL 注入問題 statement = "SELECT id, name FROM users WHERE 1=1" params = [] if min_level is not None: statement += " AND level >= ?" params.append(min_level) if gender is not None: statement += " AND gender >= ?" params.append(gender) if has_membership: statement += " AND has_membership == true" else: statement += " AND has_membership == false" statement += " ORDER BY ?" params.append(sort_field) return list(conn.execute(statement, params))
這樣做雖然看起來簡單,符合直覺,但是隨著函數(shù)邏輯變得復(fù)雜,這段代碼會(huì)變得容易出錯(cuò)。
更好的選擇是利用一些開源的對象化模塊來操作他們。
這里使用了 SQLAlchemy
。
def fetch_users_v2(conn, min_level=None, gender=None, has_membership=False, sort_field="created"): """獲取用戶列表 """ query = select([users.c.id, users.c.name]) if min_level is not None: query = query.where(users.c.level >= min_level) if gender is not None: query = query.where(users.c.gender == gender) query = query.where(users.c.has_membership == has_membership).order_by(users.c[sort_field]) return list(conn.execute(query))
其它的替換思路:
Q: 目標(biāo)/源字符串是結(jié)構(gòu)化的,遵循某種格式嗎?
其它的開源的對象化模塊。
SQL:SQLAlchemy
XML:lxml
JSON、YAML …
嘗試使用模板引擎而不是復(fù)雜字符串處理邏輯來達(dá)到目的。
Jinja2
Mako
Mustache
def f1(delta_seconds): # 如果時(shí)間已經(jīng)過去了超過 11 天,不做任何事 if delta_seconds > 950400: return ...
“為什么我們不直接把代碼寫成 if delta_seconds < 11 * 24 * 3600: 呢?”
“性能”,答案一定會(huì)是“性能”。 Python 是一門解釋型語言,所以預(yù)先計(jì)算出 950400 正是因?yàn)槲覀儾幌胱屆看螌瘮?shù) f1 的調(diào)用都帶上這部分的計(jì)算開銷。
不過事實(shí)是:即使我們把代碼改成 if delta_seconds < 11 * 24 * 3600:,函數(shù)也不會(huì)多出任何額外的開銷。
當(dāng)我們的代碼中需要出現(xiàn)復(fù)雜計(jì)算的字面量時(shí),請保留整個(gè)算式吧。它對性能沒有任何影響,而且會(huì)增加代碼的可讀性。
def f1(delta_seconds): if delta_seconds < 11 * 24 * 3600: return
True
和 False
可以當(dāng)成 1 和 0 使用
>>> True + 1 2 >>> 1 / False Traceback (most recent call last): File "<stdin>", line 1, in <module> ZeroDivisionError: division by zero
計(jì)數(shù)簡化操作。
>>> l = [1, 2, 4, 5, 7] >>> sum(i % 2 == 0 for i in l) 2
如果將某個(gè)布爾值表達(dá)式作為列表的下標(biāo)使用,可以實(shí)現(xiàn)類似三元表達(dá)式的目的:
# 類似的三元表達(dá)式:"Javascript" if 2 > 1 else "Python" >>> ["Python", "Javascript"][2 > 1] 'Javascript'
對于字符串我們常使用 \ 和 + 來講字符串拆分成好幾段。
還有一種簡單的方法是用 ()。
用 ()括起來就可以隨意拆行了。
s = ( "There is something really bad happened during the process. " "Please contact your administrator." )
對于多級(jí)縮進(jìn)字符串:
可以調(diào)用其他的標(biāo)準(zhǔn)庫來達(dá)到簡化效果。
from textwrap import dedent def main(): if user.is_active: # dedent 將會(huì)縮進(jìn)掉整段文字最左邊的空字符串 message = dedent("""\ Welcome, today's movie list: - Jaw (1975) - The Shining (1980) - Saw (2004)""")
大數(shù)字也可以變得更加可閱讀:
在數(shù)字之間加入下劃線。
>>> 10_000_000.0 # 以“千”為單位劃分?jǐn)?shù)字 10000000.0 >>> 0xCAFE_F00D # 16進(jìn)制數(shù)字同樣有效,4個(gè)一組更易讀 3405705229 >>> 0b_0011_1111_0100_1110 # 二進(jìn)制也有效 16206 >>> int('0b_1111_0000', 2) # 處理字符串的時(shí)候也會(huì)正確處理下劃線 240
例如 : .split() 和 .rsplit() 的區(qū)別是,一個(gè)從左到右分割字符串,另一個(gè)是從右到左處理字符串。
合理使用一些現(xiàn)成 string 操作函數(shù)可以讓工作事半功倍。
float ( " inf " )
和 float ( " -inf ")
,對應(yīng)著無窮大和無窮小。
float( " -inf ") < 任意數(shù)值 < float( " inf ")
一些可以用上的場合。
# A. 根據(jù)年齡升序排序,沒有提供年齡放在最后邊 >>> users = {"tom": 19, "jenny": 13, "jack": None, "andrew": 43} >>> sorted(users.keys(), key=lambda user: users.get(user) or float('inf')) ['jenny', 'tom', 'andrew', 'jack'] # B. 作為循環(huán)初始值,簡化第一次判斷邏輯 >>> max_num = float('-inf') >>> # 找到列表中最大的數(shù)字 >>> for i in [23, 71, 3, 21, 8]: ...: if i > max_num: ...: max_num = i ...: >>> max_num 71
如下:這個(gè)操作并不是線程安全的。
這個(gè)簡單的累加語句,會(huì)被編譯成包括取值和保存在內(nèi)的好幾個(gè)不同步驟。
而在多線程環(huán)境下,任意一個(gè)其他線程都有可能在其中某個(gè)步驟切入進(jìn)來,阻礙你獲得正確的結(jié)果。
def incr(value): value += 1 # 使用 dis 模塊查看字節(jié)碼 import dis dis.dis(incr) 0 LOAD_FAST 0 (value) 2 LOAD_CONST 1 (1) 4 INPLACE_ADD 6 STORE_FAST 0 (value) 8 LOAD_CONST 0 (None) 10 RETURN_VALUE
常用 dis
模塊去驗(yàn)證自己的操作,有時(shí)候,結(jié)果和我們預(yù)想的并不一樣。
Python 的字符串拼接(+=)在 2.2 以及之前的版本確實(shí)很慢。
但之后的版本做了更新,效率已經(jīng)大大提升,所有字符串的拼接還是可以使用的。
感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“python使用數(shù)字與字符串方法技巧有哪些”這篇文章對大家有幫助,同時(shí)也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。