本文將介紹15個簡潔的Python技巧,向著簡潔更高效,學習易懂出發,

目錄
- 1.通過多個鍵值將物件進行排序
- 2.資料類別
- 3.串列推導
- 4.檢查物件的記憶體使用情況
- 5.查找最頻繁出現的值
- 6.屬性包
- 7.合并字典(Python3.5+)
- 8.回傳多個值
- 9.串列元素的過濾
- filter()的使用
- 10.修改串列
- map()的使用
- 11.利用zip()來組合串列
- 12.顛倒串列
- 13.檢查串列中元素的存在情況
- 14.展平嵌套串列
- 15.檢查唯一性
1.通過多個鍵值將物件進行排序
假設要對以下字典串列進行排序:
people = [
{ 'name': 'John', "age": 64 },
{ 'name': 'Janet', "age": 34 },
{ 'name': 'Ed', "age": 24 },
{ 'name': 'Sara', "age": 64 },
{ 'name': 'John', "age": 32 },
{ 'name': 'Jane', "age": 34 },
{ 'name': 'John', "age": 99 },
]
不僅要按名字或年齡對其進行排序,還要將兩個欄位同時進行排序,在SQL中,會是這樣的查詢:
SELECT * FROM people ORDER by name, age
實際上,這個問題的解決方法可以非常簡單,Python保證sort函式提供了穩定的排序順序,這也意味著比較相似的項將保留其原始順序,要實作按名字和年齡排序,可以這樣做:
import operator
people.sort(key=operator.itemgetter('age'))
people.sort(key=operator.itemgetter('name'))
要注意如何反轉順序,首先按年齡分類,然后按名字分類,使用operator.itemgetter()從串列中的每個字典中獲取年齡和名字欄位,這樣你就會得到想要的結果:
[
{'name': 'Ed', 'age': 24},
{'name': 'Jane', 'age': 34},
{'name': 'Janet','age': 34},
{'name': 'John', 'age': 32},
{'name': 'John', 'age': 64},
{'name': 'John', 'age': 99},
{'name': 'Sara', 'age': 64}
]
名字是主要排序項,如果姓名相同,則以年齡排序,因此,所有John都按年齡分組在一起,
2.資料類別
自3.7版之后,Python開始能提供資料類別,比起常規類或其他替代方法(如回傳多個值或字典),它有著更多優點:
- 資料類需要很少的代碼
- 可以比較資料類,因為 eq 可以實作此功能
- 資料類需要型別提示,減少了發生錯誤的可能性
- 可以輕松列印資料類以進行除錯,因為__repr__可以實作此功能
這是一個作業中的資料類示例:
from dataclasses import dataclass
@dataclass
classCard:
rank: str
suit: str
card=Card("Q", "hearts")
print(card == card)
# True
print(card.rank)
# 'Q'
print(card)
Card(rank='Q', suit='hearts')
3.串列推導
串列推導可以在串列填寫里代替討厭的回圈,其基本語法為
[ expression for item in list if conditional ]
來看一個非常基本的示例,用數字序列填充串列:
mylist = [i for i inrange(10)]
print(mylist)
# [0, 1, 2, 3,4, 5, 6, 7, 8, 9]
因為可以使用運算式,所以你還可以進行一些數學運算:
squares = [x**2for x inrange(10)]
print(squares)
# [0, 1, 4, 9,16, 25, 36, 49, 64, 81]
甚至能呼叫外部函式:
defsome_function(a):
return (a +5) /2
my_formula= [some_function(i) for i inrange(10)]
print(my_formula)
# [2.5, 3.0,3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0]
最后,可以使用if函式來篩選串列,在這種情況下,只保留可被2除的值:
filtered = [i for i inrange(20) if i%2==0]
print(filtered)
# [0, 2, 4, 6,8, 10, 12, 14, 16, 18]
4.檢查物件的記憶體使用情況
使用sys.getsizeof()可以檢查物件的記憶體使用情況:
import sys
mylist =range(0, 10000)
print(sys.getsizeof(mylist))
# 48
為什么這個龐大的串列只有48個位元組呢,這是因為range函式回傳的類表現為串列,與使用實際的數字串列相比,數序列的存盤效率要高得多,我們可以通過串列推導來創建相同范圍內的實際數字串列:
import sys
myreallist = [x for x inrange(0, 10000)]
print(sys.getsizeof(myreallist))
# 87632
通過使用sys.getsizeof(),我們可以了解更多關于Python和記憶體使用情況的資訊,
5.查找最頻繁出現的值
要查找串列或字串中最頻繁出現的值:
test = [1, 2, 3, 4, 2, 2, 3, 1, 4, 4, 4]
print(max(set(test), key = test.count))
# 4
- max()將回傳串列中的最大值,key引數采用單個引數函式自定義排序順序,在本例中為test.count,該函式適用于迭代器上的每個專案,
- test.count是list的內置功能,它接受一個引數,并計算該引數的出現次數,因此test.count(1)將回傳2,而test.count(4)將回傳4,
- set(test)回傳test中的所有唯一值,所以{1、2、3、4}
那么在這一行代碼將接受test的所有唯一值,即{1、2、3、4},接下來,max將對其應用list.count 函式并回傳最大值,
還有一種更有效的方法:
from collections import Counter
Counter(test).most_common(1)
# [4: 4]
6.屬性包
你可以使用attrs代替資料類,選擇attrs有兩個原因:
- 使用的Python版本高于3.7
- 想要更多功能
Theattrs軟體包支持所有主流Python版本,包括CPython 2.7和PyPy,一些attrs可以提供驗證器和轉換器這種超常規資料類,來看一些示例代碼:
@attrs
classPerson(object):
name =attrib(default='John')
surname =attrib(default='Doe')
age =attrib(init=False)
p =Person()
print(p)
p=Person('Bill', 'Gates')
p.age=60
print(p)
# Output:
# Person(name='John', surname='Doe',age=NOTHING)
# Person(name='Bill', surname='Gates', age=60)
實際上,attrs的作者已經在使用引入資料類的PEP了,資料類被有意地保持得更簡單、更容易理解,而attrs 提供了可能需要的所有特性,
7.合并字典(Python3.5+)
dict1 = { 'a': 1, 'b': 2 }
dict2= { 'b': 3, 'c': 4 }
merged= { **dict1, **dict2 }
print (merged)
# {'a': 1, 'b':3, 'c': 4}
如果有重疊的鍵,第一個字典中的鍵將被覆寫,在Python 3.9中,合并字典變得更加簡潔,上面Python 3.9中的合并可以重寫為:
merged = dict1 | dict2
8.回傳多個值
Python中的函式在沒有字典,串列和類的情況下可以回傳多個變數,它的作業方式如下:
defget_user(id):
# fetch user from database
# ....
return name, birthdate
name, birthdate =get_user(4)
這是有限的回傳值,但任何超過3個值的內容都應放入一個(資料)類,
9.串列元素的過濾
filter()的使用
filter()函式接受2個引數:
- 函式物件
- 可迭代的物件
接下來我們定義1個函式然后對1個串列進行過濾,
首先我們創建1個串列,并且剔除掉小于等于3的元素:
original_list = [ 1,2,3,4,5]#定義串列
#定義過濾函式
4 def filter_three(number):5
return number > 3
filtered = filter(filter_three, original_list)
filtered_list = list(filtered)
filtered_list
#[4,5]
我們定義了串列original_list接著我們定義了一個接受數值型引數number的函式filter_three,當傳入的引數值大于3時會回傳True,反之則會回傳False我們定義了filter物件filtered,其中filter()接受的第一個引數是函式物件,第二個引數是串列物件最終我們將filter物件轉化為串列,最終得到經filter_three過濾后original_list內留下的元素,
類似的,我們也可以利用串列推導式來過濾串列元素,作為一種生成和修改串列優雅的方式,下面是使用串列推導完成同樣任務的程序:
original_list = [1,2,3,4,5]2
filtered_list = [ number for number in original_list if number > 3]#在串列推導程序中引入條件判斷
print(filtered_list)
#[4,5]
10.修改串列
map()的使用
Python中內置的map()函式使得我們可以將某個函式應用到可迭代物件內每一個元素之上,
比方說我們想獲取到一個串列物件中每一個元素的平方,就可以使用到map()函式,就像下面的例子一樣:
original_list = [1,2,3,4,5]
def square( number):
return number **2
squares =map(square, original_list)
squares_list = list( squares)
print(squares_list)
#[1,4,9,16,25]
類似filter()的作業程序,下面我們來看看發生了什么:
首先我們定義了串列original_list,以及接受數值型引數并回傳其平方值的函式square()接著我們定義了map物件squares,類似filter(),map()接受的第一個引數是函式物件,第二個引數是串列物件最終我們將map物件squares串列化,就得到了想要的結果,
同樣的我們也可以使用串列推導式完成同樣的任務:
original_list = [1,2,3,4,5]
squares_list = [number ** 2for number in original_list]
print(squares_list)
#[1,4,9, 16,25]
11.利用zip()來組合串列
有些情況下我們需要將兩個或以上數量的串列組合在一起,這類需求使用zip()來完成非常方便,
zip()函式接收多個串列作為引數傳入,進而得到每個位置上一一對應的元素組合,就像下面的例子一樣:
numbers = [ 1,2,3]
letters = [ 'a', 'b', 'c']
combined = zip(numbers,letters)
combined_list = list( combined)
print(combined_list)
for item in zip( numbers,letters ):
print(item[0], '\t', item[1])
#[(1,'a'),(2,'b'),(3, 'c')]
#1 a
#2 b
#3 c
12.顛倒串列
Python中的串列是有序的資料結構,正因如此,串列中元素的順序很重要,有些時候我們需要翻轉串列中所有元素的順序,可以通過Python中的切片操作,用::-1來快捷地實作:
original_list = [1,2,3,4,5]
reversed_list = original_list[ : : -1]
print('翻轉前: ', original_list)
print('翻轉后:', reversed_list)
#翻轉前:[ 1,2,3,4,5]
#翻轉后:[5,4,3,2,1]
13.檢查串列中元素的存在情況
有些情況下我們想要檢查串列中是否存在某個元素,這種時候就可以使用到Python中的in運算子,譬如說我們有一個記錄了所有比賽獲勝隊伍名稱的串列,當我們想查詢某個隊名是否已獲勝時,可以像下面的例子一樣:
games = [ 'Yankees ', 'Yankees ', 'Cubs ', 'Blue Jays ', 'Giants ']
def isin(item,list_name) :
if item in list_name: print(f"{item} is in the list! ")
else: print(f"{item} is not in the list! ")
isin( 'Blue Jays ' , games)
isin( ' Angels', games)
#Blue Jays is in the list!
#Angels is not in the list!
14.展平嵌套串列
有些情況下我們會遇到一些嵌套的串列,其每個元素又是各自不同的串列,這種時候我們就可以利用串列推導式來把這種嵌套串列展平,如下面2層嵌套的例子:
nested_list = [[1,2,3],[4,5,6],[7,8,9]]
flat_list = [i for j in nested_list for i in j]
print(flat_list)
#[1,2,3,4,5,6,7,8,9]
額外補充:
這里只考慮到兩層嵌套的串列,如果是更多層嵌套,就需要有多少層寫多少for回圈,比較麻煩,其實還有一種更好的方法,我們可以使用pip install dm-tree來安裝tree這個專門用于展平嵌套結構的庫,可以展平任意層嵌套串列,使用例子如下:
import tree
nested_list_2d = [[1,2,3],[4,5,6],[7,8,9]]
nested_list_3d = [[[1,2],[3,4]],
[[5,6],[7,8]],
[[9,10],[11,12]]]
print(tree.flatten(nested_list_2d))
print(tree.flatten(nested_list_3d))
#[1,2,3,4,5,6,7,8,9]
#[1,2,3,4,5,6,7,,8, 9, 10, 11,12]
15.檢查唯一性
如果你想要查看串列中的值是否都是唯一值,可以使用Python中的set資料結構的特點,譬如下面的例子:
list1 = [ 1,2,3,4,5]
list2 = [1,1,2,3,4]
def isunique( 1):
if len(l) == len(set(l)) :
print( 唯一! ')
eise: print(('不唯—! ')
isunique( list1)
isunique(list2)
#唯—!
#不唯—!
你們的三連(點贊,收藏,評論)是我持續輸出的動力,感謝,
資源共享,學習交流,可以加我微信:bobin1124
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/336244.html
標籤:python
上一篇:Linux全面決議講解
