Python中的任何序列(可迭代的物件)都可以通過賦值操作進行拆分,包括但不限于元組、串列、字串、檔案、迭代器、生成器等,
元組拆分
元組拆分是最為常見的一種拆分,示例如下:
p = (4, 5)
x, y = p
print(x, y) # 4 5
如果寫成
x, y, z = p
那么就會拋出ValueError例外:“not enough values to unpack (expected 3, got 2)”
如果寫成
p = (4, 5, 6)
x, y = p
那么就會拋出ValueError例外:“too many values to unpack (expected 2)”
字串拆分
字串的拆分示意如下:
s = 'Hello'
a, b, c, d, e = s
print(a) # H
拆分時丟棄值
如果在拆分時想丟棄某些特定的值,可以用一個用不到的變數名來作為丟棄值的名稱(常選'_'做為變數名),如下所示:
s = 'Hello'
a, b, _, d, _ = s
print(a) # H
嵌套序列拆分
Python也提供簡潔的對嵌套序列進行拆分的語法,如下所示我們對一個比較復雜的異質串列進行拆分:
data = https://www.cnblogs.com/lonelyprince7/archive/2021/10/09/['zhy', 50, 123.0, (2000, 12, 21)]
name, shares, price, (year, month, day) = data
print(year) # 2000
如果你想完整地得到(2000, 12, 21)這個表示時間戳的元組,那么你就得這樣寫:
data = https://www.cnblogs.com/lonelyprince7/archive/2021/10/09/['zhy', 50, 123.0, (2000, 12, 21)]
name, shares, price, date = data
print(date) # (2000, 12, 21)
從任意長度的可迭代物件中拆分
之前我們說過,如果我們想從可迭代物件中分解出\(N\)個元素,但如果這個可迭代物件長度超過\(N\),則會拋出例外"too many values to unpack",針對這個問題的解決方案是采用"*"運算式,
比如我們給定學生的分數,想去掉一個最高分和一個最低分,然后對剩下的學生求平均分,我們可以這樣寫:
def avg(data: list):
return sum(data)/len(data)
# 去掉最高分,最低分然后做均分統計
def drop_first_last(grades):
first, *middle, last = grades
return avg(middle)
print(drop_first_last([1,2,3,4])) # 2.5
還有一種情況是有一些用戶記錄,記錄由姓名+電子郵件+任意數量的電話號碼組成,則我們可以這樣分解用戶記錄:
record = ['zhy', '[email protected]', '773-556234', '774-223333']
name, email, *phone_numbers = record
print(phone_numbers) # ['773-556234', '774-223333']
事實上,如果電話號碼為空也是合法的,此時phone_numbers為空串列,
record = ['zhy', '[email protected]']
name, email, *phone_numbers = record
print(phone_numbers) # []
還有一種使用情況則更為巧妙,如果我們需要遍歷變長元組組成的串列,這些元組長度不一,那么此時*運算式可大大簡化我們的代碼,
records = [('foo', 1, 2), ('bar', 'hello'), ('foo', 3, 4)]
for tag, *args in records:
if tag == 'bar':
print(args)
# ['hello']
在對一些復雜的字串進行拆分時,*運算式也顯得特別有用,
line = "nobody:*:-2:-2:-2:Unprivileged User:/var/empty:/usr/bin/false"
uname, *fields, home_dir, sh = line.split(':')
print(home_dir) # /var/empty
*運算式也可以和我們前面說的嵌套拆分和變數丟棄一起結合使用,
record = ['ACME', 50, 123.45, (128, 18, 2012)]
name, *_, (*_, year) = record
print(year) # 2012
最后再介紹*運算式用于遞回函式的一種黑魔法,比如與遞回求和結合可以這樣寫:
items = [1, 10, 7, 4, 5, 9]
def sum(items):
head, *tail = items
return head + sum(tail) if tail else head
print(sum(items)) # 36
不過,Python由于自身遞回堆疊的限制,并不擅長遞回,我們最后一個遞回的例子可以做為一種學術上的嘗試,但不建議在實踐中使用它,
參考文獻
- [1] Martelli A, Ravenscroft A, Ascher D. Python cookbook[M]. " O'Reilly Media, Inc.", 2005.
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/307115.html
標籤:其他
上一篇:Java中List同ArrayList有什么不同呢?
下一篇:cgb2108-day07
