必須知道的python專屬騷技巧25例

一、原地交換

Python 提供了一個直觀的在一行代碼中賦值與交換(變量值)的方法


x, y = 10, 20

print(x, y)

x, y = y, x

print(x, y)

#1 (10, 20)

#2 (20, 10)

原理:賦值的右側(cè)形成了一個新的元組,左側(cè)立即解析(unpack)那個(未被引用的)元組到變量 <a> 和 <b>。一旦賦值完成,新的元組變成了未被引用狀態(tài)并且被標(biāo)記為可被垃圾回收,最終也完成了變量的交換。

二、鏈狀比較操作符

Python不用很多條件一個一個寫,比較操作符可以聚合。

n = 10

result = 1 < n < 20

print(result)

# True

result = 1 > n <= 9

print(result)

# False

三、三元操作符進(jìn)行條件賦值

三元操作符是 if-else 語句也就是條件操作符的一個快捷方式:[表達(dá)式為真的返回值] if [表達(dá)式] else [表達(dá)式為假的返回值]

這里給出一個你可以用來使代碼緊湊簡潔的例子。下面的語句是說“如果 y 是 9,給 x 賦值 10,不然賦值為 20”。

x = 10 if (y == 9) else 20

?在列表推導(dǎo)中:

[m**2 if m > 10 else m**4 for m in range(50)]

判斷最小值:

def small(a, b, c):

? ? return a if a <= b and a <= c else (b if b <= a and b <= c else c)

類中:

x = (classA if y == 1 else classB)(param1, param2)


四、多行字符串

這個比c方便多了,c打上換行符再加上轉(zhuǎn)義,真的很難受

a='''dvfssd

fsdfdsfsd

dsdsfbfdfasf

afasfaf'''

print(a)

五、in判斷

可以直接用來判斷某個變量是否在列表中

我們可以使用下面的方式來驗證多個值:

if m in [1,3,5,7]:

而不是:

if m==1 or m==3 or m==5 or m==7:


六、?四種翻轉(zhuǎn)字符串/列表的方式


# 翻轉(zhuǎn)列表本身

testList?=?[1,?3,?5]

testList.reverse()

print(testList)

#-> [5, 3, 1]


# 在一個循環(huán)中翻轉(zhuǎn)并迭代輸出

for?element?in?reversed([1,3,5]):

????print(element)

#1-> 5

#2-> 3

#3-> 1


# 一行代碼翻轉(zhuǎn)字符串

"Test Python"[::-1]

#輸出 “nohtyP tseT”


# 使用切片翻轉(zhuǎn)列表

[1, 3, 5][::-1]

#輸出 [5,3,1]。


七、一次性初始化多個變量


?可以直接賦值:

a,b,c,d=1,2,3,4

可以利用列表:

List = [1,2,3]

x,y,z=List

print(x, y, z)

#-> 1 2 3

(元素個數(shù)應(yīng)與列表長度相同)


八、打印模塊路徑


import socket

print(socket)

#<module 'socket' from '/usr/lib/python2.7/socket.py'>

九、字典推導(dǎo)

Python不光列表用推導(dǎo)式,字典/集合也有

#列表

l=[[0 for i in range(4)] for i in range(4)]#生成二維列表

print(l)

#? [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]

testDict = {i: i * i for i in xrange(10)}

testSet = {i * 2 for i in xrange(10)}

print(testSet)

print(testDict)

#set([0, 2, 4, 6, 8, 10, 12, 14, 16, 18])

#{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}

十、拼接字符串

眾所周知,python中字符串可以相加:

a="i "

b="love "

c="you"

print(a+b+c)

拼接列表中的所有元素為一個字符串

l=['a','b','c']

print(''join(l))

#以join左邊的字符做分割

十一、循環(huán)枚舉索引


list = [10, 20, 30]

for i, value in enumerate(list):

? ? print(i, ': ', value)

#1-> 0 : 10

#2-> 1 : 20

#3-> 2 : 30

很方便的找到下標(biāo)和對應(yīng)元素


十二、返回多個值

并沒有太多編程語言支持這個特性,然而 Python 中的方法確實(可以)返回多個值

def a():

? ? return 1,2,3,4,5


十三、開啟文件分享

Python 允許運行一個 HTTP 服務(wù)器來從根路徑共享文件,下面是開啟服務(wù)器的命令:

python3 -m http.server

上面的命令會在默認(rèn)端口也就是 8000 開啟一個服務(wù)器,你可以將一個自定義的端口號以最后一個參數(shù)的方式傳遞到上面的命令中。


十四、調(diào)試腳本

我們可以在 <pdb> 模塊的幫助下在 Python 腳本中設(shè)置斷點,例子:

import pdb

pdb.set_trace()

十五直接迭代序列元素

對序列(str、list、tuple等),直接迭代序列元素,比迭代元素的索引速度要更快。

>>> l=[0,1,2,3,4,5]

>>> for i in l:

print(i)

#快

>>> for i in range(len(l)):

print(l[i])

#慢

十六、巧用else語句(重要)

python的else 子句不僅能在 if 語句中使用,還能在 for、while 和 try 等語句中使用,這個語言特性不是什么秘密,但卻沒有得到重視。

for:

l=[1,2,3,4,5]

for i in l:

? ? if i=='6':

? ? ? ? print(666)

? ? ? ? break

else:

? ? print(999)

如果不這么實現(xiàn),我們只能設(shè)置一個變量來記錄了:

l=[1,2,3,4,5]

a=1

for i in l:

? ? if i=='6':

? ? ? ? print(666)

? ? ? ? a=0

? ? ? ? break

if a:

? ? print(999)

while和for類似

看一下try:

try:

? ? a()

except OSError:

? ? #語句1

else:

? ? #語句2

僅當(dāng) try 塊中沒有異常拋出時才運行 else 塊。

總結(jié)一下else:

for:

  僅當(dāng) for 循環(huán)運行完畢時(即 for 循環(huán)沒有被 break 語句中止)才運行 else 塊。

while:

  僅當(dāng) while 循環(huán)因為條件為假值而退出時(即 while 循環(huán)沒有被break 語句中止)才運行 else 塊。

try:

  僅當(dāng) try 塊中沒有異常拋出時才運行 else 塊。

即,如果異?;蛘?return、break 或 continue 語句導(dǎo)致控制權(quán)跳到了復(fù)合語句的主塊之外,那么else 子句也會被跳過。


?按正常的理解應(yīng)該是“要么運行這個循環(huán),要么做那件事”。可是,在循環(huán)中,else 的語義恰好相反:“運行這個循環(huán),然后做那件事。”


十七、except的用法和作用

try/except: 捕捉由PYTHON自身或?qū)懗绦蜻^程中引發(fā)的異常并恢復(fù)

except: 捕捉所有其他異常

except name: 只捕捉特定的異常

except name, value: 捕捉異常及格外的數(shù)據(jù)(實例)

except (name1,name2) 捕捉列出來的異常

except (name1,name2),value: 捕捉任何列出的異常,并取得額外數(shù)據(jù)

else: 如果沒有引發(fā)異常就運行

finally: 總是會運行此處代碼


十八、Python自省

這個也是python彪悍的特性.自省就是面向?qū)ο蟮恼Z言所寫的程序在運行時,所能知道對象的類型.簡單一句就是運行時能夠獲得對象的類型.比如type(),dir(),getattr(),hasattr(),isinstance().


十九、python容器

列表:元素可變(任何數(shù)據(jù)類型),有序(可索引),append/insert/pop;

元組:元素不可變,但元素中的可變元素是可變的;有序(可索引);而且元組可以被散列,例如作為字典的鍵。

集合:無序(不可被索引)、互異

字典:無序,鍵值對(key:value),key唯一不可重復(fù)


二十、map()

map()函數(shù)接收兩個參數(shù),一個是函數(shù),一個是Iterable,map將傳入的函數(shù)依次作用到序列的每個元素,并把結(jié)果作為新的Iterator返回。(重點理解)

舉例說明,比如我們有一個函數(shù)f(x)=x2,要把這個函數(shù)作用在一個list [1, 2, 3, 4, 5, 6, 7, 8, 9]上,就可以用map()實現(xiàn)如下:

>>> def f(x):

...? ? return x * x

...

>>> r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])

>>> list(r)

[1, 4, 9, 16, 25, 36, 49, 64, 81]

map()作為高階函數(shù),事實上它把運算規(guī)則抽象了,因此,我們不但可以計算簡單的f(x)=x2,還可以計算任意復(fù)雜的函數(shù),比如,把這個list所有數(shù)字轉(zhuǎn)為字符串:

>>> list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))

['1', '2', '3', '4', '5', '6', '7', '8', '9']


二十一、reduce

reduce把一個函數(shù)作用在一個序列[x1, x2, x3, ...]上,這個函數(shù)必須接收兩個參數(shù),reduce把結(jié)果繼續(xù)和序列的下一個元素做累積計算

簡單例子:

>>> from functools import reduce

>>> def fn(x, y):

? ? ? ? return x * 10 + y

>>> reduce(fn, [1, 3, 5, 7, 9])

13579

結(jié)合一下,我們可以自己寫出int()函數(shù)

from functools import reduce

a={'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}

def charnum(s):

? ? return a[s]

def strint(s):

? ? return reduce(lambda x, y: x * 10 + y, map(charnum, s))


我們繼續(xù)說一些好用的函數(shù)

二十二、split

Python?split()?通過指定分隔符對字符串進(jìn)行切片,如果參數(shù) num 有指定值,則僅分隔 num 個子字符串。

語法:

str.split(str="", num=string.count(str))

簡化:

str.split("")

二十三、理論結(jié)合實際


1)結(jié)合第四期所學(xué)知識,我們可以寫出這一行代碼

print(" ".join(input().split(" ")[::-1]))

實現(xiàn)功能,leetcode原題:給定一個句子(只包含字母和空格),將句子中的單詞位置反轉(zhuǎn),單詞用空格分割,單詞之間只有一個空格,前后沒有空格。比如:(1)“hello xiao mi” - >“ mi xiao你好“


2)再舉一例:

將兩個整型數(shù)組按照升序合并,并且過濾掉重復(fù)數(shù)組元素

輸入?yún)?shù):

int*?pArray1?:整型數(shù)組1

intiArray1Num:數(shù)組1元素個數(shù)

int*?pArray2?:整型數(shù)組2

intiArray2Num:數(shù)組2元素個數(shù)

對于python來說,給個數(shù)沒什么卵用。

a,b,c,d=input(),list(map(int,input().split())),input(),list(map(int,input().split()))

print("".join(map(str,sorted(list(set(b+d))))))


3)我們把最近的知識結(jié)合起來做一道題:

輸入一個int型整數(shù),按照從右向左的閱讀順序,返回一個不含重復(fù)數(shù)字的新的整數(shù)。

result=""

for i in input()[::-1]:

? ? if i not in result:

? ? ? ? result+=i

print(result)

還有很多具體的簡潔操作,這里就不再舉例子了,多體會吧。

好,我們繼續(xù)其它函數(shù)。


二十四、filter

Python內(nèi)建的filter()函數(shù)用于過濾序列。

和map()類似,filter()也接收一個函數(shù)和一個序列。和map()不同的是,filter()把傳入的函數(shù)依次作用于每個元素,然后根據(jù)返回值是True還是False決定保留還是丟棄該元素。

簡單例子,刪掉偶數(shù):

def is_odd(n):

? ? return n % 2 == 1

list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))

# 結(jié)果: [1, 5, 9, 15]

我們可以用所學(xué)知識實現(xiàn)埃氏篩:

埃氏篩相關(guān)知識:https://blog.csdn.net/hebtu666/article/details/81486370

本代碼非原創(chuàng):

#先構(gòu)造一個從3開始的奇數(shù)序列:

def _odd_iter():

? ? n = 1

? ? while True:

? ? ? ? n = n + 2

? ? ? ? yield n

#這是一個生成器,并且是一個無限序列。

#篩選函數(shù)

def _not_divisible(n):

? ? return lambda x: x % n > 0

#生成器

def primes():

? ? yield 2

? ? it = _odd_iter() # 初始序列

? ? while True:

? ? ? ? n = next(it) # 返回序列的第一個數(shù)

? ? ? ? yield n

? ? ? ? it = filter(_not_divisible(n), it) # 構(gòu)造新序列

利用filter()不斷產(chǎn)生篩選后的新的序列

Iterator是惰性計算的序列,所以我們可以用Python表示“全體自然數(shù)”,“全體素數(shù)”這樣的序列,而代碼非常簡潔。


二十五、sorted


>>> sorted([36, 5, -12, 9, -21])

[-21, -12, 5, 9, 36]

#可以接收一個key函數(shù)來實現(xiàn)自定義的排序,例如按絕對值大小排序:

>>> sorted([36, 5, -12, 9, -21], key=abs)

[5, 9, -12, -21, 36]

我們再看一個字符串排序的例子:

>>> sorted(['bob', 'about', 'Zoo', 'Credit'])

['Credit', 'Zoo', 'about', 'bob']

默認(rèn)情況下,對字符串排序,是按照ASCII的大小比較的,由于'Z' < 'a',結(jié)果,大寫字母Z會排在小寫字母a的前面。

現(xiàn)在,我們提出排序應(yīng)該忽略大小寫,按照字母序排序。要實現(xiàn)這個算法,不必對現(xiàn)有代碼大加改動,只要我們能用一個key函數(shù)把字符串映射為忽略大小寫排序即可。忽略大小寫來比較兩個字符串,實際上就是先把字符串都變成大寫(或者都變成小寫),再比較。

這樣,我們給sorted傳入key函數(shù),即可實現(xiàn)忽略大小寫的排序:

>>> sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower)

['about', 'bob', 'Credit', 'Zoo']

要進(jìn)行反向排序,不必改動key函數(shù),可以傳入第三個參數(shù)reverse=True:

>>> sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True)

['Zoo', 'Credit', 'bob', 'about']

從上述例子可以看出,高階函數(shù)的抽象能力是非常強(qiáng)大的,而且,核心代碼可以保持得非常簡潔。

sorted()也是一個高階函數(shù)。用sorted()排序的關(guān)鍵在于實現(xiàn)一個映射函數(shù)。

好了,今天的分享就到這,如果你對Python感興趣,歡迎加入我們【python學(xué)習(xí)交流裙】,免費領(lǐng)取學(xué)習(xí)資料和源碼。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容