日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

word 代码块_如何优雅的写好 Pythonic 代码?

發(fā)布時間:2025/3/15 python 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 word 代码块_如何优雅的写好 Pythonic 代码? 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

(點擊上方公眾號,可快速關(guān)注一起學(xué)Python)

Python 與其它語言(比如Java或者C++)相比有比較大的區(qū)別,其中最大的特點就是非常簡潔。如果按照其它語言的思路來寫Python代碼,則會使得代碼繁瑣復(fù)雜,并且容易出現(xiàn)Bug。在Python語言中,有個詞很火,Pythonic。有的同學(xué)可能不明白這個詞的意義,小編的理解就是用Python的寫法寫代碼,而非是其它語言的通用的寫法,寫出Python的特點,寫出Python的風(fēng)格

下面,就通過幾個示例來看一下不同思維的Python代碼的差異。

1、變量值交換

這個問題最常見,大家從最開始寫Java及C++等語言代碼都會遇到這個問題。通常是通過一個臨時變量來實現(xiàn)的:

tmp = a
a = b
b = tmp

而Python中可以直接交換兩個變量,即:

a, b = b, a

2、列表推導(dǎo)式

列表推導(dǎo)式是Java及C++等語言沒有的特性,能夠很簡潔的實現(xiàn)for循環(huán),可以應(yīng)用于列表,集合或者字典。

例如我們要求20以內(nèi)的整除3的數(shù)的平方的列表,可以用如下代碼實現(xiàn):

numbers = []
for x in xrange(20):
? ?if x % 3 == 0:
? ? ? ?numbers.append(x*x)

而通過列表推導(dǎo)式一行代碼即可實現(xiàn):

numbers = [x*x for x in range(20) if x % 3 == 0]

列表推導(dǎo)式也可以用于集合和字典,將[...]變?yōu)閧...}即可。集合和字典的實現(xiàn)如下所示:

集合:

numbers = {x * x for x in range(0, 20) if x % 3 == 0}

字典:

numbers = {x: x * x for x in range(0, 20) if x % 3 == 0}

3、字符串拼接

這是一個老生常談的問題,當(dāng)我們需要將數(shù)個字符串拼接的時候,習(xí)慣性的使用 "+" 作為連接字符串的手段。

然而,由于像字符串這種不可變對象在內(nèi)存中生成后無法修改,合并后的字符串會重新開辟出一塊內(nèi)存空間來存儲。因此每合并一次就會單獨開辟一塊內(nèi)存空間,這樣會占用大量的內(nèi)存空間,嚴重影響代碼的效率。

words = ['I', ' ', 'love', ' ', 'Python', '.']

sentence = ''
for word in words:
? ?sentence += '' + word

解決這個問題的辦法是使用字符串連接的join,Python寫法如下:

words = ['I', ' ', 'love', ' ', 'Python', '.']

sentence = ''.join(words)

4、如何快速翻轉(zhuǎn)字符串

Java或者C++等語言的寫法是新建一個字符串,從最后開始訪問原字符串:

a = 'I love Python.'

reverse_a = ''
for i in range(0, len(a)):
? ?reverse_a += a[len(a) - i - 1]

而Python則將字符串看作list,而列表可以通過切片操作來實現(xiàn)反轉(zhuǎn):

a = 'I love Python.'
reverse_a = a[::-1]

5、for/else語句

在C語言或Java語言中,我們尋找一個字符是否在一個list中,通常會設(shè)置一個布爾型變量表示是否找到:

cities = ['BeiJing', 'TianJin', 'JiNan', 'ShenZhen', 'WuHan']
tofind = 'Shanghai'

found = False
for city in cities:
? ?if tofind == city:
? ? ? ?print 'Found!'
? ? ? ?found = True
? ? ? ?break
if not found:
? ?print 'Not found!'

而Python中的通過for...else...會使得代碼很簡潔,注意else中的代碼塊僅僅是在for循環(huán)中沒有執(zhí)行break語句的時候執(zhí)行:

cities = ['BeiJing', 'TianJin', 'JiNan', 'ShenZhen', 'WuHan']
tofind = 'Shanghai'

for city in cities:
? ?if tofind == city:
? ? ? ?print 'Found!'
? ? ? ?break
else:
? ?# 執(zhí)行else中的語句意味著沒有執(zhí)行break
? ?print 'Not found!'

另外,while以及try關(guān)鍵字都可以和else搭配使用,具體可以參考小編之前寫的文章 ?Python中else塊那點事。

6、迭代對象善用enumerate類

enumerate類接收兩個參數(shù),其中一個是可以迭代的對象,另外一個是開始的索引。比如,我們想要打印一個列表的索引及其內(nèi)容,可以用如下代碼實現(xiàn):

cities = ['BeiJing', 'TianJin', 'JiNan', 'ShenZhen', 'WuHan']

index = 0
for city in cities:
? ?index = index + 1
? ?print index, ':', city

而通過使用enumerate則極大簡化了代碼,這里索引設(shè)置為從1開始(默認是從0開始):

cities = ['BeiJing', 'TianJin', 'JiNan', 'ShenZhen', 'WuHan']
for index, city in enumerate(cities, 1):
? ?print index, ":", city

7、通過lambda來定義函數(shù)

lambda可以返回一個可以調(diào)用的函數(shù)對象,會使得代碼更為簡潔。若不使用lambda則需要單獨定義一個函數(shù):

def f(x):
? ?return x * x

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

使用lambda后僅僅需要一行代碼:

map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9])

這里注意,lambda生成的是一個可以像其他函數(shù)一樣使用的函數(shù)對象,即

def f(x):
? ?return x * x

等價于??

lambda x: x * x

8、應(yīng)用上下文管理

在打開文件時,通常是通過捕獲異常來進行實現(xiàn)的,并且在finally模塊中對文件來進行關(guān)閉:

try:
? ?file = open('python.txt')
? ?for line in file:
? ? ? ?print line
except:
? ?print "File error!"
finally:
? ?file.close()

而通過上下文管理中的with語句可以讓代碼非常簡潔:

with open('python.txt') as file:
? ?for line in file:
? ? ? ?print line

具體原理可以參考小編之前寫的?with語句那點事。

9、使用裝飾器

裝飾器在Python中應(yīng)用特別廣泛,其特點是可以在具體函數(shù)執(zhí)行之前或者之后做相關(guān)的操作,比如:執(zhí)行前打印執(zhí)行函數(shù)的相關(guān)信息,對函數(shù)的參數(shù)進行校驗;執(zhí)行后記錄函數(shù)調(diào)用的相關(guān)流水日志等。使用裝飾器最大的好處是使得函數(shù)功能單一化,僅僅處理業(yè)務(wù)邏輯,而不附帶其它功能

在函數(shù)調(diào)用前打印時間函數(shù)名相關(guān)的信息,不使用裝飾器可以用如下代碼實現(xiàn):

from time import ctime

def foo():
? ?print('[%s] ?%s() is called' % (ctime(), foo.__name__))
? ?print('Hello, Python')

這樣寫的問題是業(yè)務(wù)邏輯中會夾雜參數(shù)檢查,日志記錄等信息,使得代碼邏輯不夠清晰。所以,這種場景需要使用裝飾器:

from time import ctime

def deco(func):
? ?def decorator(*args, **kwargs):
? ? ? ?print('[%s] ?%s() is called' % (ctime(), func.__name__))
? ? ? ?return func(*args, **kwargs)
? ?return decorator

@deco
def foo():
? ?print('Hello, Python')

如果想深入理解裝飾器,可以閱讀小編之前寫的?深入理解Python中的裝飾器。

10、使用生成器

生成器與列表最大的區(qū)別就是,列表是一次性生成的,需要較大的內(nèi)存空間;而生成器是需要的時候生成的,基本不占用內(nèi)存空間。生成器分為生成器表達式和生成器函數(shù)。

先看一下列表:

l = [x for x in range(10)]

改為生成器只需要將[...]變?yōu)?...),即

g = (x for x in range(10))

至于生成器函數(shù),是通過yield關(guān)鍵字來實現(xiàn)的,我們以計算斐波那契數(shù)列為例,使用列表可以用如下代碼來實現(xiàn):

def fib(max):
? ?n, a, b = 0, 0, 1
? ?fibonacci = []
? ?while n < max:
? ? ? ?fibonacci.append(b)
? ? ? ?a, b = b, a + b
? ? ? ?n = n + 1
? ?return fibonacci

而使用生成器則變?yōu)?#xff1a;

def fib(max):
? ?n, a, b = 0, 0, 1
? ?while n < max:
? ? ? ?yield b
? ? ? ?a, b = b, a + b
? ? ? ?n = n + 1

對生成器感興趣的可以深入閱讀小編之前寫的文章?生成器那點事?及?深入理解生成器及協(xié)程。

11、Counter的使用

通常的詞頻統(tǒng)計中,我們的思路是:

需要一個字典,key值存儲單詞,value存儲對應(yīng)的詞頻。當(dāng)遇到一個單詞,判斷是否在這個字典中,如果是,則詞頻加1;如果否,則字典中新增這個單詞,同時對應(yīng)的詞頻設(shè)置為1。

對應(yīng)的Python代碼實現(xiàn)如下:

#統(tǒng)計單詞出現(xiàn)的頻次
def computeFrequencies(wordList):
? ?#詞頻字典
? ?wordfrequencies = {}

? ?for word in wordList:
? ? ? ?if word not in wordfrequencies:
? ? ? ? ? ?# 單詞不在單詞詞頻字典中, 詞頻設(shè)置為1
? ? ? ? ? ?wordfrequencies[word] = 1
? ? ? ?else:
? ? ? ? ? ?# 單詞在單詞詞頻字典中, 詞頻加1
? ? ? ? ? ?wordfrequencies[word] = wordfrequencies[word] ?+ 1
? ? return wordfrequencies

有沒有更簡單的方式呢?答案是肯定的,就是使用Counter。collection 中的 Counter 類就完成了這樣的功能,它是字典類的一個子類。Python代碼變得無比簡潔:

# 統(tǒng)計單詞出現(xiàn)的頻次
def computeFrequencies(wordList):
? ?#詞頻字典
? ?wordfrequencies = Counter(wordList)
? ?return wordfrequencies

感興趣的可以深入閱讀小編之前寫的文章?Python中的詞頻統(tǒng)計。

12、鏈式比較

在實際數(shù)字比較中,我們可能需要多次比較多次,比如我們判斷學(xué)習(xí)成績是否位于某個區(qū)間:

x = 79

>>> x < 80 and x > 70
True

而更Pythonic的寫法變身鏈式比較,即:

x = 79

>>> 80 < x < 90
False

>>> 70 < x < 80
True

這種寫法給人的感受也更為直觀易懂。

13、函數(shù)返回多個值

在Java語言中,當(dāng)函數(shù)需要返回多個值時,通常的做法是生成一個Response對象,然后將要返回的值寫入對象內(nèi)部。而Python不需要這樣做,可以直接返回多個值:

def f():
? ?error_code = 0
? ?error_desc = "成功"
? ?return error_code, error_desc

使用的時候也會非常簡單:

code, desc = f()
print code, desc

14、使用*運算符

*運算符和** 運算符完美的解決了將元組參數(shù)、字典參數(shù)進行? unpack,從而簡化了函數(shù)定義的形式,如:

def fun(*args):
? ?for eacharg in args:
? ? ? ?print 'tuple arg:', eacharg

fun('I', 'love', 'Python')

運行的結(jié)果為:

tuple arg: I

tuple arg: love

tuple arg: Python

感興趣的可以深入閱讀小編之前寫的文章?Python 中的*args和**kwargs。

15、找出列表中出現(xiàn)最多的數(shù)

這是經(jīng)常會遇到的一個問題。解決這個問題的其中一個思路是按照標(biāo)題11提供的詞頻統(tǒng)計的方法,先統(tǒng)計詞頻,然后遍歷字典,找出具有最大詞頻的數(shù)字。有沒有更簡潔的方式?

當(dāng)然,Python代碼如下:

num = [1, 3, 3, 4, 5, 6, 3, 6, 6, 6]

print ?max(set(num),key=num.count)

這些Pythonic的代碼是否讓你耳目一新?你還能寫出哪些Pythonic的代碼?在留言區(qū)跟大家分享一下吧!

提醒福利

之前給大家推薦的《Python核心技術(shù)與實戰(zhàn)》還在優(yōu)惠期,原價¥99,限時優(yōu)惠¥68,不要錯過了。既然你要學(xué)Python為什么不跟著知名公司的一線程序員學(xué)吶?100天,帶你進階高手。掃碼免費試看

(完)

看完本文有收獲?請轉(zhuǎn)發(fā)分享給更多人

關(guān)注「Python那些事」,做全棧開發(fā)工程師

點「在看」的人都變好看了哦

總結(jié)

以上是生活随笔為你收集整理的word 代码块_如何优雅的写好 Pythonic 代码?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。