在Python3中初學(xué)者應(yīng)會(huì)的一些基本的提升效率的小技巧
有時(shí)候我反問(wèn)我自己,怎么不知道在Python 3中用更簡(jiǎn)單的方式做“這樣”的事,當(dāng)我尋求答案時(shí),隨著時(shí)間的推移,我當(dāng)然發(fā)現(xiàn)更簡(jiǎn)潔、有效并且bug更少的代碼??偟膩?lái)說(shuō)(不僅僅是這篇文章),“那些”事情總共數(shù)量是超過(guò)我想象的,但這里是第一批不明顯的特性,后來(lái)我尋求到了更有效的/簡(jiǎn)單的/可維護(hù)的代碼。
字典
字典中的keys()和items()
你能在字典的keys和items中做很多有意思的操作,它們類(lèi)似于集合(set):
aa = {‘mike': ‘male', ‘kathy': ‘female', ‘steve': ‘male', ‘hillary': ‘female'} bb = {‘mike': ‘male', ‘ben': ‘male', ‘hillary': ‘female'} aa.keys() & bb.keys() # {‘mike', ‘hillary'} # these are set-like aa.keys() - bb.keys() # {‘kathy', ‘steve'} # If you want to get the common key-value pairs in the two dictionaries aa.items() & bb.items() # {(‘mike', ‘male'), (‘hillary', ‘female')}
太簡(jiǎn)潔啦!
在字典中校驗(yàn)一個(gè)key的存在
下面這段代碼你寫(xiě)了多少遍了?
dictionary = {} for k, v in ls: if not k in dictionary: dictionary[k] = [] dictionary[k].append(v)
這段代碼其實(shí)沒(méi)有那么糟糕,但是為什么你一直都需要用if語(yǔ)句呢?
from collections import defaultdict dictionary = defaultdict(list) # defaults to list for k, v in ls: dictionary[k].append(v)
這樣就更清晰了,沒(méi)有一個(gè)多余而模糊的if語(yǔ)句。
用另一個(gè)字典來(lái)更新一個(gè)字典
from itertools import chain a = {‘x': 1, ‘y':2, ‘z':3} b = {‘y': 5, ‘s': 10, ‘x': 3, ‘z': 6} # Update a with b c = dict(chain(a.items(), b.items())) c # {‘y': 5, ‘s': 10, ‘x': 3, ‘z': 6}
這樣看起來(lái)還不錯(cuò),但是不夠簡(jiǎn)明。看看我們是否能做得更好:
c = a.copy() c.update(b)
更清晰而且更有可讀性了!
從一個(gè)字典獲得最大值
如果你想獲取一個(gè)字典中的最大值,可能會(huì)像這樣直接:
aa = {k: sum(range(k)) for k in range(10)} aa # {0: 0, 1: 0, 2: 1, 3: 3, 4: 6, 5: 10, 6: 15, 7: 21, 8: 28, 9: 36} max(aa.values()) #36
這么做是有效的,但是如果你需要key,那么你就需要在value的基礎(chǔ)上再找到key。然而,我們可以用過(guò)zip來(lái)讓展現(xiàn)更扁平化,并返回一個(gè)如下這樣的key-value形式:
max(zip(aa.values(), aa.keys())) # (36, 9) => value, key pair
同樣地,如果你想從最大到最小地去遍歷一個(gè)字典,你可以這么干:
sorted(zip(aa.values(), aa.keys()), reverse=True) # [(36, 9), (28, 8), (21, 7), (15, 6), (10, 5), (6, 4), (3, 3), (1, 2), (0, 1), (0, 0)]
在一個(gè)list中打開(kāi)任意數(shù)量的items
我們可以運(yùn)用*的魔法,獲取任意的items放到list中:
def compute_average_salary(person_salary): person, *salary = person_salary return person, (sum(salary) / float(len(salary))) person, average_salary = compute_average_salary([“mike”, 40000, 50000, 60000]) person # ‘mike' average_salary # 50000.0
這不是那么有趣,但是如果我告訴你也可以像下面這樣呢:
def compute_average_salary(person_salary_age): person, *salary, age = person_salary_age return person, (sum(salary) / float(len(salary))), age person, average_salary, age = compute_average_salary([“mike”, 40000, 50000, 60000, 42]) age # 42
看起來(lái)很簡(jiǎn)潔嘛!
當(dāng)你想到有一個(gè)字符串類(lèi)型的key和一個(gè)list的value的字典,而不是遍歷一個(gè)字典,然后順序地處理value,你可以使用一個(gè)更扁平的展現(xiàn)(list中套list),像下面這樣:
# Instead of doing this for k, v in dictionary.items(): process(v) # we are separating head and the rest, and process the values # as a list similar to the above. head becomes the key value for head, *rest in ls: process(rest) # if not very clear, consider the following example aa = {k: list(range(k)) for k in range(5)} # range returns an iterator aa # {0: [], 1: [0], 2: [0, 1], 3: [0, 1, 2], 4: [0, 1, 2, 3]} for k, v in aa.items(): sum(v) #0 #0 #1 #3 #6 # Instead aa = [[ii] + list(range(jj)) for ii, jj in enumerate(range(5))] for head, *rest in aa: print(sum(rest)) #0 #0 #1 #3 #6
你可以把list解壓成head,*rest,tail等等。
Collections用作計(jì)數(shù)器
Collections是我在python中最喜歡的庫(kù)之一,在python中,除了原始的默認(rèn)的,如果你還需要其他的數(shù)據(jù)結(jié)構(gòu),你就應(yīng)該看看這個(gè)。
我日?;竟ぷ鞯囊徊糠志褪怯?jì)算大量而又不是很重要的詞??赡苡腥藭?huì)說(shuō),你可以把這些詞作為一個(gè)字典的key,他們分別的值作為value,在我沒(méi)有接觸到collections中的Counter時(shí),我可能會(huì)同意你的做法(是的,做這么多介紹就是因?yàn)镃ounter)。
假設(shè)你讀的python語(yǔ)言的維基百科,轉(zhuǎn)化為一個(gè)字符串,放到一個(gè)list中(標(biāo)記好順序):
import re word_list = list(map(lambda k: k.lower().strip(), re.split(r'[;,:(.s)]s*', python_string))) word_list[:10] # [‘python', ‘is', ‘a(chǎn)', ‘widely', ‘used', ‘general-purpose', ‘high-level', ‘programming', ‘language', ‘[17][18][19]']
到目前為止看起來(lái)都不錯(cuò),但是如果你想計(jì)算這個(gè)list中的單詞:
from collections import defaultdict # again, collections! dictionary = defaultdict(int) for word in word_list: dictionary[word] += 1
這個(gè)沒(méi)有那么糟糕,但是如果你有了Counter,你將會(huì)節(jié)約下你的時(shí)間做更有意義的事情。
from collections import Counter counter = Counter(word_list) # Getting the most common 10 words counter.most_common(10) [(‘the', 164), (‘a(chǎn)nd', 161), (‘a(chǎn)', 138), (‘python', 138), (‘of', 131), (‘is', 102), (‘to', 91), (‘in', 88), (‘', 56)] counter.keys()[:10] # just like a dictionary [‘', ‘limited', ‘a(chǎn)ll', ‘code', ‘managed', ‘multi-paradigm', ‘exponentiation', ‘fromosing', ‘dynamic']
很簡(jiǎn)潔吧,但是如果我們看看在Counter中包含的可用的方法:
dir(counter) [‘__add__', ‘__and__', ‘__class__', ‘__cmp__', ‘__contains__', ‘__delattr__', ‘__delitem__', ‘__dict__', ‘__doc__', ‘__eq__', ‘__format__', ‘__ge__', ‘__getattribute__', ‘__getitem__', ‘__gt__', ‘__hash__', ‘__init__', ‘__iter__', ‘__le__', ‘__len__', ‘__lt__', ‘__missing__', ‘__module__', ‘__ne__', ‘__new__', ‘__or__', ‘__reduce__', ‘__reduce_ex__', ‘__repr__', ‘__setattr__', ‘__setitem__', ‘__sizeof__', ‘__str__', ‘__sub__', ‘__subclasshook__', ‘__weakref__', ‘clear', ‘copy', ‘elements', ‘fromkeys', ‘get', ‘has_key', ‘items', ‘iteritems', ‘iterkeys', ‘itervalues', ‘keys', ‘most_common', ‘pop', ‘popitem', ‘setdefault', ‘subtract', ‘update', ‘values', ‘viewitems', ‘viewkeys', ‘viewvalues']
你看到__add__和__sub__方法了嗎,是的,Counter支持加減運(yùn)算。因此,如果你有很多文本想要去計(jì)算單詞,你不必需要Hadoop,你可以運(yùn)用Counter(作為map)然后把它們加起來(lái)(相當(dāng)于reduce)。這樣你就有構(gòu)建在Counter上的mapreduce了,你可能以后還會(huì)感謝我。
扁平嵌套lists
Collections也有_chain函數(shù),其可被用作扁平嵌套lists
from collections import chain ls = [[kk] + list(range(kk)) for kk in range(5)] flattened_list = list(collections._chain(*ls))
同時(shí)打開(kāi)兩個(gè)文件
如果你在處理一個(gè)文件(比如一行一行地),而且要把這些處理好的行寫(xiě)入到另一個(gè)文件中,你可能情不自禁地像下面這么去寫(xiě):
with open(input_file_path) as inputfile: with open(output_file_path, ‘w') as outputfile: for line in inputfile: outputfile.write(process(line))
除此之外,你可以在相同的一行里打開(kāi)多個(gè)文件,就像下面這樣:
with open(input_file_path) as inputfile, open(output_file_path, ‘w') as outputfile: for line in inputfile: outputfile.write(process(line))
這樣就更簡(jiǎn)潔啦!
從一堆數(shù)據(jù)中找到星期一
如果你有一個(gè)數(shù)據(jù)想去標(biāo)準(zhǔn)化(比如周一之前或是之后),你也許會(huì)像下面這樣:
import datetime previous_monday = some_date - datetime.timedelta(days=some_date.weekday()) # Similarly, you could map to next monday as well next_monday = some_date + date_time.timedelta(days=-some_date.weekday(), weeks=1)
這就是實(shí)現(xiàn)方式。
處理HTML
如果你出于興趣或是利益要爬一個(gè)站點(diǎn),你可能會(huì)一直面臨著html標(biāo)簽。為了去解析各種各樣的html標(biāo)簽,你可以運(yùn)用html.parer:
from html.parser import HTMLParser class HTMLStrip(HTMLParser): def __init__(self): self.reset() self.ls = [] def handle_data(self, d): self.ls.append(d) def get_data(self): return ‘'.join(self.ls) @staticmethod def strip(snippet): html_strip = HTMLStrip() html_strip.feed(snippet) clean_text = html_strip.get_data() return clean_text snippet = HTMLStrip.strip(html_snippet)
如果你僅僅想避開(kāi)html:
escaped_snippet = html.escape(html_snippet) # Back to html snippets(this is new in Python 3.4) html_snippet = html.unescape(escaped_snippet) # and so forth ...
- 幾個(gè)提升Python運(yùn)行效率的方法之間的對(duì)比
- 盤(pán)點(diǎn)提高 Python 代碼效率的方法
- 提升Python程序運(yùn)行效率的6個(gè)方法
- Python while、for、生成器、列表推導(dǎo)等語(yǔ)句的執(zhí)行效率測(cè)試
- Python 多線程抓取圖片效率對(duì)比
- 六個(gè)竅門(mén)助你提高Python運(yùn)行效率
- Python中map和列表推導(dǎo)效率比較實(shí)例分析
- Python利用IPython提高開(kāi)發(fā)效率
- 教你用Type Hint提高Python程序開(kāi)發(fā)效率
- 分享Python開(kāi)發(fā)中要注意的十個(gè)小貼士
相關(guān)文章
python numpy中mat和matrix的區(qū)別
這篇文章主要介紹了python numpy中mat和matrix的區(qū)別,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-03-03python負(fù)載均衡的簡(jiǎn)單實(shí)現(xiàn)方法
這篇文章給大家介紹用python實(shí)現(xiàn)最簡(jiǎn)單的負(fù)載均衡方法,即將請(qǐng)求發(fā)送到未宕機(jī)的服務(wù)器上,感興趣的朋友一起看看吧2018-02-02解決pytorch下只打印tensor的數(shù)值不打印出device等信息的問(wèn)題
這篇文章主要介紹了解決pytorch下只打印tensor的數(shù)值不打印出device等信息的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-05-05Python中計(jì)算三角函數(shù)之cos()方法的使用簡(jiǎn)介
這篇文章主要介紹了Python中計(jì)算三角函數(shù)之cos()方法的使用簡(jiǎn)介,是Python入門(mén)的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-05-05python3 pillow生成簡(jiǎn)單驗(yàn)證碼圖片的示例
本篇文章主要介紹了python3 pillow生成簡(jiǎn)單驗(yàn)證碼圖片的示例,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-09-09Django獲取該數(shù)據(jù)的上一條和下一條方法
今天小編就為大家分享一篇Django獲取該數(shù)據(jù)的上一條和下一條方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-08-08