摘要:但是實(shí)際寫程序中,我們經(jīng)常會(huì)寫出許多繁雜的丑陋的代碼。特別推薦,許多代碼讓我獲益匪淺,比如這里對的使用。用可以寫出很簡單直觀的代碼,如下當(dāng)然,上面不考慮效率,這里有一個(gè)利用分治法思想的高效的方法。更多文章更多閱讀中參數(shù)的用法高級編程技巧
用 Python 時(shí)間也算不短了,但總感覺自己在用寫 C++ 代碼的思維寫 Python,沒有真正用到其作為腳本語言的優(yōu)勢。之前刷 LeetCode 時(shí),自己的 Python 代碼總是很長,很像披著 Python 外衣的 C++ 代碼(放在這里,不斷重構(gòu)中)。
想來大概是因?yàn)橛X得python簡單,平時(shí)只是零零碎碎的學(xué)習(xí),也沒有去讀別人的代碼,導(dǎo)致掌握的不夠深入。回想起前段時(shí)間的面試,面試官看我簡歷寫熟悉Python,就問了兩個(gè)Python的問題:
Python 中常用的優(yōu)化技巧(能夠提升 Python 執(zhí)行效率的,除了算法層面)
按照 value 從小到大輸出 dict 中的 key-value值。
我支支吾吾半天,就是沒有答到點(diǎn)上,直接導(dǎo)致被拒(后來整理的內(nèi)容放在這里)。所謂知恥而后勇,經(jīng)過一段時(shí)間對 Python 的重新學(xué)習(xí),才慢慢發(fā)現(xiàn) Python 的一些強(qiáng)大與美妙之處。
從排序說起!程序中經(jīng)常用到排序函數(shù),Python 提供了 sort 和 sorted 函數(shù),一個(gè)原地排序,一個(gè)返回排序后的新結(jié)果,函數(shù)原型很簡單:
sort([cmp[, key[, reverse]]])
自己用的最多的類似下面的語句:
>>> l = [43, 12, 4, 6] >>> l.sort() >>> l [4, 6, 12, 43]
曾經(jīng)竊以為這就體現(xiàn)了 Python 的簡單優(yōu)雅,不像 C++ STL中那樣還需要指定迭代器范圍,然后對 sort 的理解也就止步于此。后來遇到稍微復(fù)雜一點(diǎn)的排序場景,自己就 Google-Stackoverflow-Copy,解決了眼前的問題,但是從來沒有去深挖(這也就導(dǎo)致那次面試中中沒有回答出來上面的第二個(gè)問題)。
sort 之美后來去看了下 sort 的函數(shù)說明,包括 cmp, key, reverse 參數(shù)究竟怎么去用,又寫了幾個(gè)例子,以為這下子對 sort 可謂是理解透徹了。比如要要根據(jù)值的大小輸出字典內(nèi)容,那么就可以像下面這樣優(yōu)雅地解決:
>>> d = {1: "z", 2:"y", 3: "x"} >>> print sorted(d.items(), key=lambda x: x[1]) [(3, "x"), (2, "y"), (1, "z")]
我甚至可以得到一個(gè)根據(jù)value排序的字典,只需要用 collections.OrderedDict 即可:
>>> from collections import OrderedDict >>> sorted_d = OrderedDict(sorted(d.items(), key=lambda x: x[1])) >>> sorted_d OrderedDict([(3, "x"), (2, "y"), (1, "z")])sort 之魅
我以為我對 sort 理解足夠了,直到在 hackerrank 遇到這個(gè)題目。
給定一個(gè)只包含大小寫字母,數(shù)字的字符串,對其進(jìn)行排序,保證:
所有的小寫字母在大寫字母前面
所有的字母在數(shù)字前面
所有的奇數(shù)在偶數(shù)前面
考慮用 sort 函數(shù)來完成排序。開始之前,再來看看文檔對sort函數(shù)中key的說明:
key parameter to specify a function to be called on each list element prior to making comparisons. The value of the key parameter should be a function that takes a single argument and returns a key to use for sorting purposes.
通俗講,key 用來決定在排序算法中 cmp 比較的內(nèi)容,key 可以是任何可被比較的內(nèi)容,比如元組(python 中元組是可被比較的)。所以上面的排序問題可以用下面的代碼來解決:
>>> s = "Sorting1234" >>> "".join(sorted(s, key=lambda x: (x.isdigit(), x.isdigit() and int(x) % 2 == 0, x.isupper(), x.islower(), x))) "ginortS1324"
這里,lambda 函數(shù)將輸入的字符轉(zhuǎn)換為一個(gè)元組,然后 sorted 函數(shù)將根據(jù)元組(而不是字符)來進(jìn)行比較,進(jìn)而判斷每個(gè)字符的前后順序。
如果同樣的程序用 C++ 來寫的話,可能需要一個(gè)復(fù)雜的仿函數(shù),來定義排序的規(guī)則,遠(yuǎn)沒有 Python 這般簡潔優(yōu)雅。
再探 PythonPython 是一門簡單方便的語言,相信這是大部分人對 Python 的第一感覺。初學(xué) Python,我們可能癡迷于 Python 的列表解析,list 切片,字典推導(dǎo),或者是陶醉在各種強(qiáng)大的第三方庫里,比如網(wǎng)絡(luò)庫 requests,科學(xué)計(jì)算庫 numpy,web開發(fā)框架 Django 等。
但是實(shí)際寫程序中,我們經(jīng)常會(huì)寫出許多繁雜的、丑陋的Python代碼。比如要判斷一個(gè)數(shù)字是否是回文數(shù)字,可能會(huì)習(xí)慣性地寫出下面這樣的代碼:
def isPalindrome(x): if x < 0: return False reversed_x = 0 original_x = x while x > 0: reversed_x = reversed_x * 10 + x % 10 x /= 10 return reversed_x == original_x
仔細(xì)一看,這簡直就是 C++ 代碼,完全沒有 Python 的優(yōu)雅與簡單。那么,該怎樣寫才能夠顯的 Pythonic 呢?其實(shí),用 Python 的話只要一行就可以啦(這里不考慮效率,如果考慮效率的話,C++會(huì)更加合適,單對這題來說,其實(shí)有比上面更高效的方法)!
def isPalindrome(x): return x >= 0 and str(x) == str(x)[::-1]
那么如何養(yǎng)成用 Pythonic 的思維解決問題呢?我覺得首先要對 Python 十分熟悉,精通大部分函數(shù)以及 Python 的特色:比如裝飾器,迭代器,生成器以等,下面舉幾個(gè)簡單的例子:
# 函數(shù)式編程 >>> nums = map(int, "123456789" ) >>> nums [1, 2, 3, 4, 5, 6, 7, 8, 9] >>> reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) 15 >>> sum(nums) 45 # 生成器 >>> mygenerator = (x*x for x in range(3)) >>> for i in mygenerator: ... print i ... 0 1 4 >>> for i in mygenerator: ... print i ... # lambda 匿名函數(shù) >>> c = lambda *z: z >>> c( 10, "test") (10, "test") # 迭代 >>> l = [i**2 for i in range(9)] >>> l_iter = iter(l) >>> next(l_iter) 0 >>> next(l_iter) 1 >>> next(l_iter) 4 # 數(shù)據(jù)結(jié)構(gòu) set >>> set_a = set([i for i in range(1,9,2)]) >>> set_b = set([i for i in range(0,9,2)]) >>> print set_a | set_b set([0, 1, 2, 3, 4, 5, 6, 7, 8])
其次,要多讀一些 Pythonic 的代碼,學(xué)習(xí)別人如何優(yōu)雅地使用python。這里我推薦去看 Leetcode 的 Discuss,里面有許多驚才艷艷的代碼。特別推薦 @StefanPochmann,許多代碼讓我獲益匪淺,比如這里對 iter() 的使用。
再來看一個(gè)問題,按照二進(jìn)制位反轉(zhuǎn) 32 位的一個(gè)整形無符號數(shù)字。用 Python 可以寫出很簡單直觀的代碼,如下:
def reverseBits(n): bit_str = "{0:032b}".format(n) reverse_str = bit_str[::-1] return int(reverse_str, 2)
當(dāng)然,上面不考慮效率,這里有一個(gè)利用分治法思想的高效的方法。
Python 是一門高效、簡單、方便的語言,但這并不意味你不花時(shí)間就可以用的很好。
更多文章
更多閱讀Sorting Mini-HOW TO
sort()中cmp參數(shù)的用法
hackerrank: ginortS
Sort a Python dictionary by value
Python高級編程技巧
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/37896.html
摘要:返回值是一個(gè)經(jīng)過排序的可迭代類型,與一樣。注一般來說,和可以使用表達(dá)式。與的不同在于,是在原位重新排列列表,而是產(chǎn)生一個(gè)新的列表。 我們需要對List進(jìn)行排序,Python提供了兩個(gè)方法 對給定的List L進(jìn)行排序,方法1.用List的成員函數(shù)sort進(jìn)行排序方法2.用built-in函數(shù)sorted進(jìn)行排序(從2.4開始) ----------------------------...
摘要:嘗射于家圃,有賣油翁釋擔(dān)而立,睨之,久而不去。康肅問曰汝亦知射乎吾射不亦精乎翁曰無他,但手熟爾。康肅忿然曰爾安敢輕吾射翁曰以我酌油知之。 開啟變身模式 大家好, 從這一期開始,我們會(huì)從小白變身為中等小白,在基礎(chǔ)起步階段有太多的東西我沒有講到,但是俗話說的好,無他,但手熟爾,只要多多練習(xí),時(shí)間會(huì)是最好的證明,相信我們終有一天會(huì)成為高手,因此從這一系列開始,讓我們一起更上一層樓,還是和往常...
摘要:用匿名函數(shù)有個(gè)好處,因?yàn)楹瘮?shù)沒有名字,不必?fù)?dān)心函數(shù)名沖突。和不同的是,把傳入的函數(shù)依次作用于每個(gè)元素,然后根據(jù)返回值是還是決定保留還是丟棄該元素。字符串給出當(dāng)前平臺使用的行終止符。程序中間的退出,為正常退出。 列表生成式 函數(shù)的參數(shù)類型 lambda函數(shù) map, reduce, filter, sorted函數(shù) eval, exec, join, zip函數(shù) itertools中的...
摘要:輸出下標(biāo)和對應(yīng)的元素集合集合是無序的,集合中的元素是唯一的,集合一般用于元組或者列表中的元素去重。 python內(nèi)置的數(shù)據(jù)類型 showImg(https://segmentfault.com/img/bVbrz1j); Python3.7內(nèi)置的關(guān)鍵字 [False, None, True, and, as, assert, async, await, break, class, co...
摘要:新年快樂大家好,今天是大年初二,身在國外沒有過年的氛圍,只能踏實(shí)寫寫文章,對社區(qū)做點(diǎn)貢獻(xiàn),在此祝大家新年快樂上一期為大家梳理了一些的進(jìn)階用法,今天我們來看字典的相關(guān)技巧,我個(gè)人在編程中對字典的使用非常頻繁,其實(shí)對于不是非常大的數(shù)據(jù)存儲需求, 新年快樂 大家好,今天是大年初二,身在國外沒有過年的氛圍,只能踏實(shí)寫寫文章,對社區(qū)做點(diǎn)貢獻(xiàn),在此祝大家新年快樂!上一期為大家梳理了一些List的進(jìn)...
閱讀 3222·2021-11-11 16:55
閱讀 2458·2021-10-13 09:39
閱讀 2392·2021-09-13 10:27
閱讀 2155·2019-08-30 15:55
閱讀 3083·2019-08-30 15:54
閱讀 3127·2019-08-29 16:34
閱讀 1819·2019-08-29 12:41
閱讀 1065·2019-08-29 11:33