Python 的 sum() Pythonic 的求和方法詳細
:
我們現(xiàn)在可以使用 Python
的內(nèi)置函數(shù)sum()
將多個數(shù)值相加。此函數(shù)提供了一種高效、可讀且 Pythonic
的方法來解決代碼中的求和問題。如果您正在處理需要對數(shù)值求和的數(shù)學計算,那么它sum()
可以成為您的救星。
Python
的內(nèi)置函數(shù)sum()
是一種對數(shù)值列表求和的有效且Pythonic
的方法。將多個數(shù)字相加是許多計算中常見的中間步驟,因此sum()
對于 Python
程序員來說是一個非常方便的工具。
作為一個額外的和有趣的使用情況,您可以連接列表和元組使用sum(),當你需要拼合列表的列表,可以很方便。
在本教程中,我們將學習如何:
- 使用通用技術(shù)和工具手工對數(shù)值求和
- 使用
Pythonsum()
高效地添加多個數(shù)值 - 拼接列表和元組與
sum()
- 使用
sum()
接近普通求和問題 - 使用適當?shù)闹档膮?shù)中
sum()
- 之間做出選擇
sum()
和替代工具來總結(jié)和串連對象
這些知識將幫助您使用sum()
或其他替代和專用工具有效地處理和解決代碼中的求和問題。
1、理解求和問題
將數(shù)值相加是編程中一個相當普遍的問題。例如,假設(shè)您有一個數(shù)字列表 [1, 2, 3, 4, 5] 并且想要將它們加在一起以計算它們的總和。使用標準算術(shù),您將執(zhí)行以下操作:
1 + 2 + 3 + 4 + 5 = 15
就數(shù)學而言,這個表達式非常簡單。它會引導您完成一系列簡短的加法,直到您找到所有數(shù)字的總和。
可以手動進行這個特定的計算,但想象一下其他一些不太可能的情況。如果您有一個特別長的數(shù)字列表,手動添加可能效率低下且容易出錯。如果您甚至不知道列表中有多少項會發(fā)生什么?最后,想象一個場景,您需要添加的項目數(shù)量動態(tài)或不可預測地發(fā)生變化。
在這種情況下,無論您的數(shù)字列表是長列表還是短列表,Python
在解決求和問題方面都非常有用。
如果您想通過從頭開始創(chuàng)建自己的解決方案來對數(shù)字求和,那么您可以嘗試使用for循環(huán):
>>> >>> numbers = [1, 2, 3, 4, 5] >>> total = 0 >>> for number in numbers: ... total += number ... >>> total 15
在這里,您首先創(chuàng)建total
并將其初始化為0. 此變量用作累加器,您可以在其中存儲中間結(jié)果,直到獲得最終結(jié)果。循環(huán)通過使用增廣賦值累加每個連續(xù)值來迭代numbers
和更新。total
您還可以將for循環(huán)包裝在函數(shù)中。這樣,我們可以為不同的列表重用代碼:
>>> >>> def sum_numbers(numbers): ... total = 0 ... for number in numbers: ...total += number ... return total ... >>> sum_numbers([1, 2, 3, 4, 5]) 15 >>> sum_numbers([]) 0
在 中sum_numbers()
,您將一個可迭代對象——特別是一個數(shù)值列表——作為參數(shù),并返回輸入列表中值的總和。如果輸入列表為空,則函數(shù)返回0。該for
循環(huán)與您之前看到的相同。
您還可以使用遞歸代替迭代。遞歸是一種函數(shù)式編程技術(shù),其中函數(shù)在其自己的定義中被調(diào)用。換句話說,遞歸函數(shù)在循環(huán)中調(diào)用自身:
>>> >>> def sum_numbers(numbers): ... if len(numbers) == 0: ...return 0 ... return numbers[0] + sum_numbers(numbers[1:]) ... >>> sum_numbers([1, 2, 3, 4, 5]) 15
當你定義一個遞歸函數(shù)時,你冒著陷入無限循環(huán)的風險。為了防止這種情況,您需要定義停止遞歸的基本情況和調(diào)用函數(shù)并啟動隱式循環(huán)的遞歸情況。
在上面的例子中,基本情況意味著零長度列表的總和是0。遞歸情況意味著總和是第一個值numbers[0]
,加上其余值的總和numbers[1:]
。由于遞歸情況在每次迭代中使用較短的序列,因此您希望在numbers
是零長度列表時遇到基本情況。作為最終結(jié)果,您將獲得輸入列表中所有項目的總和numbers
。
注意:在此示例中,如果您不檢查空輸入列表(您的基本情況),則
sum_numbers()
永遠不會遇到無限遞歸循環(huán)。當您的numbers
列表長度達到 時0,代碼會嘗試訪問空列表中的項目,這會引發(fā)IndexError
并中斷循環(huán)。使用這種實現(xiàn),你永遠不會從這個函數(shù)中得到一個總和。你
IndexError
每次都會得到一個。
在 Python
中對數(shù)字列表求和的另一種選擇是使用reduce()from functools
。要獲取數(shù)字列表的總和,我們可以將任一operator.add
或適當?shù)?code>lambda函數(shù)作為第一個參數(shù)傳遞給reduce():
>>> >>> from functools import reduce >>> from operator import add >>> reduce(add, [1, 2, 3, 4, 5]) 15 >>> reduce(add, []) Traceback (most recent call last): ... TypeError: reduce() of empty sequence with no initial value >>> reduce(lambda x, y: x + y, [1, 2, 3, 4, 5]) 15
您可以致電reduce()
與減少或折疊,function
與一起iterable
作為參數(shù)。然后reduce()
使用輸入函數(shù)處理iterable
并返回單個累積值。
在第一個示例中,歸約函數(shù)是add(),它將兩個數(shù)字相加。最終結(jié)果是 input
中數(shù)字的總和iterable
。作為一個缺點,reduce()
提出了一個TypeError
當你與一個空的調(diào)用它iterable
。
在第二個示例中,約簡函數(shù)是一個lambda
返回兩個數(shù)字相加的函數(shù)。
由于像這樣的求和在編程中很常見,因此每次需要對一些數(shù)字求和時編寫一個新函數(shù)是大量重復性工作。此外, usingreduce
()不是您可用的最易讀的解決方案。
Python
提供了專門的內(nèi)置函數(shù)來解決這個問題。該函數(shù)被方便地調(diào)用sum()
。由于它是一個內(nèi)置函數(shù),因此您可以直接在代碼中使用它,而無需導入任何內(nèi)容。
2、Python 入門 sum()
可讀性是Python
哲學背后最重要的原則之一。在對值列表求和時,可視化您要求循環(huán)執(zhí)行的操作。您希望它遍歷一些數(shù)字,將它們累加到一個中間變量中,然后返回最終和。但是,您可能可以想象一個不需要循環(huán)的更易讀的求和版本。您希望 Python 取一些數(shù)字并將它們相加。
現(xiàn)在想想如何reduce()
求和。使用reduce()
可以說比基于循環(huán)的解決方案更不可讀,更不直接。
這就是為什么將Python 2.3
添加sum()
為內(nèi)置函數(shù)來為求和問題提供 Pythonic
解決方案的原因。Alex Martelli
貢獻了這個函數(shù),它現(xiàn)在是對值列表求和的首選語法:
>>> >>> sum([1, 2, 3, 4, 5]) 15 >>> sum([]) 0
哇!這很整潔,不是嗎?它讀起來像簡單的英語,并清楚地傳達您在輸入列表上執(zhí)行的操作。使用sum()
比for
循環(huán)或reduce()
調(diào)用更具可讀性。與reduce()
,當您提供空的可迭代對象時sum()
不會引發(fā) a TypeError
。相反,它可以理解地返回0.
我們可以sum()
使用以下兩個參數(shù)進行調(diào)用:
iterable
是一個必需的參數(shù),可以保存任何 Python
可迭代對象??傻鷮ο笸ǔ0瑪?shù)值,但也可以包含列表或元組。
start是一個可選參數(shù),可以保存一個初始值。然后將該值添加到最終結(jié)果中。它默認為0.
在內(nèi)部,從左到右sum()
添加startplus
中的值iterable
。輸入iterable
中的值通常是數(shù)字,但您也可以使用列表和元組??蛇x參數(shù)start
可以接受數(shù)字、列表或元組,具體取決于傳遞給 的內(nèi)容iterable
。它不能帶一個string
。
在以下兩節(jié)中,您將了解sum()
在代碼中使用的基礎(chǔ)知識。
2.1 必需的參數(shù): iterable
接受任何 Python iterable
作為它的第一個參數(shù)使得sum()
泛型、可重用和多態(tài)。由于此功能,您可以使用sum()
列表、元組、集合、range
對象和字典:
>>> >>> # Use a list >>> sum([1, 2, 3, 4, 5]) 15 >>> # Use a tuple >>> sum((1, 2, 3, 4, 5)) 15 >>> # Use a set >>> sum({1, 2, 3, 4, 5}) 15 >>> # Use a range >>> sum(range(1, 6)) 15 >>> # Use a dictionary >>> sum({1: "one", 2: "two", 3: "three"}) 6 >>> sum({1: "one", 2: "two", 3: "three"}.keys()) 6
在所有這些示例中,sum()
計算輸入迭代中所有值的算術(shù)和,而不管它們的類型。在兩個字典示例中,都調(diào)用sum()
返回輸入字典鍵的總和。第一個示例默認對鍵求和,第二個示例由于.keys()
調(diào)用輸入字典而對鍵求和。
如果您的字典在其值中存儲數(shù)字,并且您想對這些值而不是鍵進行求和,那么您可以.values()
像.keys()
示例中那樣使用。
您還可以sum()
將列表推導式用作參數(shù)。這是一個計算一系列值的平方和的示例:
>>> >>> sum([x ** 2 for x in range(1, 6)]) 55
Python 2.4
向該語言添加了生成器表達式。同樣,sum()
當您使用生成器表達式作為參數(shù)時,按預期工作:
>>> >>> sum(x ** 2 for x in range(1, 6)) 55
這個例子展示了解決求和問題的最 Pythonic
技術(shù)之一。它在一行代碼中提供了一個優(yōu)雅、可讀且高效的解決方案。
2.2 可選參數(shù): start
第二個可選參數(shù)start
允許您提供一個值來初始化求和過程。當您需要按順序處理累積值時,此參數(shù)很方便:
>>> >>> sum([1, 2, 3, 4, 5], 100) # Positional argument 115 >>> sum([1, 2, 3, 4, 5], start=100) # Keyword argument 115
在這里,您提供初始值100
to start
。凈效果是sum()
將此值添加到輸入可迭代中的值的累積總和中。請注意,您可以start
作為位置參數(shù)或關(guān)鍵字參數(shù)提供。后一個選項更加明確和可讀。
如果您沒有為 提供值start
,則默認為0。默認值0確保返回輸入值總和的預期行為。
3、對數(shù)值求和
的主要目的sum()
是提供一種 Pythonic
方式來將數(shù)值相加。到目前為止,您已經(jīng)了解了如何使用該函數(shù)對整數(shù)求和。此外,可以使用sum()
任何其他數(shù)字Python
類型,比如float
,complex
,decimal.Decimal
,和fractions.Fraction
。
以下是使用sum()
不同數(shù)字類型的值的幾個示例:
>>> >>> from decimal import Decimal >>> from fractions import Fraction >>> # Sum floating-point numbers >>> sum([10.2, 12.5, 11.8]) 34.5 >>> sum([10.2, 12.5, 11.8, float("inf")]) inf >>> sum([10.2, 12.5, 11.8, float("nan")]) nan >>> # Sum complex numbers >>> sum([3 + 2j, 5 + 6j]) (8+8j) >>> # Sum Decimal numbers >>> sum([Decimal("10.2"), Decimal("12.5"), Decimal("11.8")]) Decimal('34.5') >>> # Sum Fraction numbers >>> sum([Fraction(51, 5), Fraction(25, 2), Fraction(59, 5)]) Fraction(69, 2)
在這里,您第一次使用sum()
與浮點數(shù)字。值得注意的是,當您使用特殊符號inf
并nan
在調(diào)用float("inf")
和 中時函數(shù)的行為float("nan")
。第一個符號代表一個無限值,因此sum()
返回inf。第二個符號代表NaN
(不是數(shù)字)值。由于您無法將數(shù)字與非數(shù)字相加,因此您會得到nan
結(jié)果。
其他的例子總和iterables
的complex
,Decimal
和Fraction
數(shù)字。在所有情況下,sum()
使用適當?shù)臄?shù)字類型返回結(jié)果累積總和。
4、連接序列
盡管sum()
主要用于對數(shù)值進行操作,但您也可以使用該函數(shù)來連接列表和元組等序列。為此,您需要為 提供適當?shù)闹祍tart:
>>> >>> num_lists = [[1, 2, 3], [4, 5, 6]] >>> sum(num_lists, start=[]) [1, 2, 3, 4, 5, 6] >>> # Equivalent concatenation >>> [1, 2, 3] + [4, 5, 6] [1, 2, 3, 4, 5, 6] >>> num_tuples = ((1, 2, 3), (4, 5, 6)) >>> sum(num_tuples, start=()) (1, 2, 3, 4, 5, 6) >>> # Equivalent concatenation >>> (1, 2, 3) + (4, 5, 6) (1, 2, 3, 4, 5, 6)
在這些示例中,您使用sum()
連接列表和元組。這是一個有趣的功能,您可以使用它來展平列表列表或元組元組。這些示例工作的關(guān)鍵要求是為 選擇適當?shù)闹祍tart。例如,如果要連接列表,則start
需要持有一個列表。
在上面的示例中,sum()
在內(nèi)部執(zhí)行連接操作,因此它僅適用于支持連接的序列類型,字符串除外:
>>> >>> num_strs = ["123", "456"] >>> sum(num_strs, "0") Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: sum() can't sum strings [use ''.join(seq) instead]
當您嘗試使用sum()來
連接字符串時,您會得到一個TypeError
. 正如異常消息所暗示的那樣,您應該使用str.join()
來連接 Python
中的字符串。稍后,當您進入使用替代sum()
方法部分時,您將看到使用此方法的示例。
5、使用 Python 進行練習 sum()
到目前為止,您已經(jīng)學習了使用sum().
您已經(jīng)學習了如何使用此函數(shù)將數(shù)值相加,以及如何連接列表和元組等序列。
在本節(jié)中,您將查看更多有關(guān)何時以及如何sum()在代碼中使用的示例。通過這些實際示例,您將了解到當您執(zhí)行需要查找一系列數(shù)字之和作為中間步驟的計算時,此內(nèi)置函數(shù)非常方便。
您還將了解到這sum()
在您使用列表和元組時會很有幫助。您將看到的一個特殊示例是當您需要展平列表列表時。
5.1 計算累積和
您將編寫的第一個示例與如何利用start參數(shù)對數(shù)值的累積列表求和有關(guān)。
假設(shè)您正在開發(fā)一個系統(tǒng)來管理給定產(chǎn)品在多個不同銷售點的銷售。每天,您都會收到來自每個銷售點的銷售單位報告。您需要系統(tǒng)地計算累計總和,以了解整個公司在一周內(nèi)銷售了多少件商品。要解決此問題,您可以使用sum()
:
>>> >>> cumulative_sales = 0 >>> monday = [50, 27, 42] >>> cumulative_sales = sum(monday, start=cumulative_sales) >>> cumulative_sales 119 >>> tuesday = [12, 32, 15] >>> cumulative_sales = sum(tuesday, start=cumulative_sales) >>> cumulative_sales 178 >>> wednesday = [20, 24, 42] >>> cumulative_sales = sum(wednesday, start=cumulative_sales) >>> cumulative_sales 264 ...
通過使用start
,您可以設(shè)置一個初始值來初始化總和,這允許您將連續(xù)單位添加到先前計算的小計中。在本周末,您將獲得公司的銷售單位總數(shù)。
5.2 計算樣本的平均值
的另一個實際用例sum()
是在進行進一步計算之前將其用作中間計算。例如,假設(shè)您需要計算數(shù)值樣本的算術(shù)平均值。算術(shù)平均值,也稱為平均值,是樣本中值的總和除以值或數(shù)據(jù)點的數(shù)量。
如果你有樣本 [2, 3, 4, 2, 3, 6, 4, 2]
并且你想手工計算算術(shù)平均值,那么你可以解決這個操作:
(2 + 3 + 4 + 2 + 3 + 6 + 4 + 2) / 8 = 3.25
如果您想通過使用 Python
加快速度,您可以將其分為兩部分。此計算的第一部分,即您將數(shù)字相加,是 的任務sum()
。運算的下一部分,即除以 8,使用樣本中的數(shù)字計數(shù)。要計算您的除數(shù),您可以使用len()
:
>>> >>> data_points = [2, 3, 4, 2, 3, 6, 4, 2] >>> sum(data_points) / len(data_points) 3.25
在這里,調(diào)用sum()
計算樣本中數(shù)據(jù)點的總和。接下來,您使用len()
來獲取數(shù)據(jù)點的數(shù)量。最后,您執(zhí)行所需的除法以計算樣本的算術(shù)平均值。
在實踐中,您可能希望將此代碼轉(zhuǎn)換為具有一些附加功能的函數(shù),例如描述性名稱和檢查空樣本:
>>> >>> # Python >= 3.8 >>> def average(data_points): ... if (num_points := len(data_points)) == 0: ...raise ValueError("average requires at least one data point") ... return sum(data_points) / num_points ... >>> average([2, 3, 4, 2, 3, 6, 4, 2]) 3.25 >>> average([]) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 3, in average ValueError: average requires at least one data point
在內(nèi)部average()
,您首先檢查輸入樣本是否有任何數(shù)據(jù)點。如果沒有,那么你ValueError
用一個描述性的消息來引發(fā)。在此示例中,您使用walrus
運算符將數(shù)據(jù)點的數(shù)量存儲在變量中,num_points
以便您無需len()
再次調(diào)用。該return
語句計算樣本的算術(shù)平均值,并將其發(fā)送回調(diào)用代碼。
注意:計算數(shù)據(jù)樣本的平均值是統(tǒng)計和數(shù)據(jù)分析中的常見操作。
Python
標準庫提供了一個方便的模塊,稱為statistics處理這些類型的計算。在
statistics
模塊中,您將找到一個名為 的函數(shù)mean()
:>>> >>> from statistics import mean >>> mean([2, 3, 4, 2, 3, 6, 4, 2]) 3.25 >>> mean([]) Traceback (most recent call last): ... statistics.StatisticsError: mean requires at least one data point該
statistics.mean()
函數(shù)的行為與average()
您之前編碼的函數(shù)非常相似。當您mean()
使用數(shù)值樣本進行調(diào)用時,您將獲得輸入數(shù)據(jù)的算術(shù)平均值。當您將空列表傳遞給 時mean()
,您將獲得一個statistics.StatisticsError.
請注意,當您average()
使用適當?shù)臉颖菊{(diào)用時,您將獲得所需的平均值。如果您average()
使用空樣本調(diào)用,那么您會得到ValueError
預期的結(jié)果。
5.3 求兩個序列的點積
您可以使用的另一個問題sum()
是找到兩個等長數(shù)值序列的點積。點積的代數(shù)和的產(chǎn)品在輸入序列的每對值中的。例如,如果您有序列 (1, 2, 3)
和 (4, 5, 6),
那么您可以使用加法和乘法手動計算它們的點積:
1 × 4 + 2 × 5 + 3 × 6 = 32
要從輸入序列中提取連續(xù)的值對,您可以使用zip(). 然后您可以使用生成器表達式將每對值相乘。最后,sum()
可以總結(jié)產(chǎn)品:
>>> >>> x_vector = (1, 2, 3) >>> y_vector = (4, 5, 6) >>> sum(x * y for x, y in zip(x_vector, y_vector)) 32
使用zip()
,您可以使用來自每個輸入序列的值生成一個元組列表。生成器表達式循環(huán)遍歷每個元組,同時將先前排列的連續(xù)值對乘以zip()
。最后一步是使用 將產(chǎn)品添加在一起sum()
。
上面示例中的代碼有效。然而,點積是為等長的序列定義的,所以如果你提供不同長度的序列會發(fā)生什么?在這種情況下,zip()
忽略最長序列中的額外值,這會導致不正確的結(jié)果。
為了處理這種可能性,我們可以將調(diào)用包裝sum()
在自定義函數(shù)中,并為輸入序列的長度提供適當?shù)臋z查:
>>> >>> def dot_product(x_vector, y_vector): ... if len(x_vector) != len(y_vector): ...raise ValueError("Vectors must have equal sizes") ... return sum(x * y for x, y in zip(x_vector, y_vector)) ... >>> dot_product((1, 2, 3), (4, 5, 6)) 32 >>> dot_product((1, 2, 3, 4), (5, 6, 3)) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 3, in dot_product ValueError: Vectors must have equal sizes
這里,dot_product()
將兩個序列作為參數(shù)并返回它們對應的點積。如果輸入序列的長度不同,則該函數(shù)會引發(fā) a ValueError
。
在自定義函數(shù)中嵌入功能允許您重用代碼。它還使您有機會對函數(shù)進行描述性命名,以便用戶僅通過閱讀函數(shù)名稱就知道該函數(shù)的作用。
5.4 展平列表列表
展平列表列表是 Python
中的一項常見任務。假設(shè)您有一個列表列表,需要將其展平為一個包含原始嵌套列表中所有項目的列表。您可以使用多種方法中的任何一種在 Python
中展平列表。例如,您可以使用for
循環(huán),如以下代碼所示:
>>> >>> def flatten_list(a_list): ... flat = [] ... for sublist in a_list: ...flat += sublist ... return flat ... >>> matrix = [ ... [1, 2, 3], ... [4, 5, 6], ... [7, 8, 9], ... ] >>> flatten_list(matrix) [1, 2, 3, 4, 5, 6, 7, 8, 9]
在 中flatten_list()
,循環(huán)遍歷 中包含的所有嵌套列表a_list
。然后它flat
使用增強賦值操作 ( +=)將它們連接起來。結(jié)果,您會得到一個平面列表,其中包含原始嵌套列表中的所有項目。
但是堅持??!您已經(jīng)sum()
在本教程中學習了如何使用來連接序列。您可以使用該功能來像上面的示例中那樣展平列表列表嗎?是的!就是這樣:
>>> >>> matrix = [ ... [1, 2, 3], ... [4, 5, 6], ... [7, 8, 9], ... ] >>> sum(matrix, []) [1, 2, 3, 4, 5, 6, 7, 8, 9]
那很快!一行代碼,matrix
現(xiàn)在是一個平面列表。但是,使用sum()
似乎不是最快的解決方案。
任何暗示串聯(lián)的解決方案的一個重要缺點是,在幕后,每個中間步驟都會創(chuàng)建一個新列表。這在內(nèi)存使用方面可能非常浪費。最終返回的列表只是在每一輪連接中創(chuàng)建的所有列表中最近創(chuàng)建的列表。使用列表推導式可確保您只創(chuàng)建和返回一個列表:
>>> >>> def flatten_list(a_list): ... return [item for sublist in a_list for item in sublist] ... >>> matrix = [ ... [1, 2, 3], ... [4, 5, 6], ... [7, 8, 9], ... ] >>> flatten_list(matrix) [1, 2, 3, 4, 5, 6, 7, 8, 9]
這個新版本flatten_list()
在內(nèi)存使用方面效率更高,浪費更少。然而,嵌套的理解可能難以閱讀和理解。
使用.append()
可能是扁平化列表列表最易讀和 Pythonic
的方式:
>>> >>> def flatten_list(a_list): ... flat = [] ... for sublist in a_list: ...for item in sublist: ... flat.append(item) ... return flat ... >>> matrix = [ ... [1, 2, 3], ... [4, 5, 6], ... [7, 8, 9], ... ] >>> flatten_list(matrix) [1, 2, 3, 4, 5, 6, 7, 8, 9]
在這個版本中flatten_list()
,一個人閱讀你的代碼可以看出,功能遍歷每個sublist
在a_list
。在第一個for
循環(huán)中,它遍歷每個iteminsublist
以最終flat使用.append().
就像前面的推導一樣,這個解決方案在這個過程中只創(chuàng)建了一個列表。這種解決方案的一個優(yōu)點是它的可讀性很強。
6、使用替代品 sum()
正如您已經(jīng)了解到的,sum()
一般來說,對于處理數(shù)值很有幫助。但是,在處理浮點數(shù)時,Python
提供了一種替代工具。在 中math
,您會找到一個名為的函數(shù)fsum()
,它可以幫助您提高浮點計算的總體精度。
您可能有一項任務,您希望連接或鏈接多個可迭代對象,以便您可以將它們作為一個整體處理。對于這種情況,您可以查看itertools
模塊的 function chain()
。
您可能還有一個要連接字符串列表的任務。您在本教程中了解到,無法sum()
用于連接字符串。這個函數(shù)不是為字符串連接而構(gòu)建的。最 Pythonic
的替代方法是使用str.join().
6.1 對浮點數(shù)求和: math.fsum()
如果您的代碼不斷使用 對浮點數(shù)求和sum()
,那么您應該考慮math.fsum()
改用 。此函數(shù)比 更仔細地執(zhí)行浮點計算sum()
,從而提高計算精度。
根據(jù)其文檔,fsum()“
通過跟蹤多個中間部分和來避免精度損失?!?該文檔提供了以下示例:
>>> >>> from math import fsum >>> sum([.1, .1, .1, .1, .1, .1, .1, .1, .1, .1]) 0.9999999999999999 >>> fsum([.1, .1, .1, .1, .1, .1, .1, .1, .1, .1]) 1.0
使用fsum()
,您可以獲得更精確的結(jié)果。但是,您應該注意這fsum()
并不能解決浮點運算中的表示錯誤。以下示例揭示了此限制:
>>> >>> from math import fsum >>> sum([0.1, 0.2]) 0.30000000000000004 >>> fsum([0.1, 0.2]) 0.30000000000000004
在這些示例中,兩個函數(shù)返回相同的結(jié)果。這是因為不可能準確地表示這兩個值0.1和0.2二進制浮點數(shù):
>>> >>> f"{0.1:.28f}" '0.1000000000000000055511151231' >>> f"{0.2:.28f}" '0.2000000000000000111022302463'
sum()
但是,與 不同的是,fsum()
當您將非常大和非常小的數(shù)字相加時,可以幫助您減少浮點錯誤傳播:
>>> >>> from math import fsum >>> sum([1e-16, 1, 1e16]) 1e+16 >>> fsum([1e-16, 1, 1e16]) 1.0000000000000002e+16 >>> sum([1, 1, 1e100, -1e100] * 10_000) 0.0 >>> fsum([1, 1, 1e100, -1e100] * 10_000) 20000.0
哇!第二個例子非常令人驚訝并且完全失敗sum()
。使用sum(),
您將得到0.0結(jié)果。這與 的正確結(jié)果相去甚遠20000.0,正如您所得到的fsum()
。
6.2 連接可迭代對象 itertools.chain()
如果您正在尋找一個方便的工具來連接或鏈接一系列可迭代對象,請考慮使用chain()from itertools
。此函數(shù)可以采用多個迭代器并構(gòu)建一個迭代器,該迭代器從第一個、第二個中產(chǎn)生項目,依此類推,直到耗盡所有輸入迭代:
>>> >>> from itertools import chain >>> numbers = chain([1, 2, 3], [4, 5, 6], [7, 8, 9]) >>> numbers <itertools.chain object at 0x7f0d0f160a30> >>> next(numbers) 1 >>> next(numbers) 2 >>> list(chain([1, 2, 3], [4, 5, 6], [7, 8, 9])) [1, 2, 3, 4, 5, 6, 7, 8, 9]
當您調(diào)用 時chain(),
您會從輸入可迭代對象中獲得項目的迭代器。在本例中,您可以numbers
使用訪問連續(xù)的項目next()
。如果你想使用一個列表,那么你可以使用它list()
來使用迭代器并返回一個常規(guī)的 Python
列表。
chain()
在 Python
中展平列表列表也是一個不錯的選擇:
>>> >>> from itertools import chain >>> matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] >>> list(chain(*matrix)) [1, 2, 3, 4, 5, 6, 7, 8, 9]
要使用 扁平化列表列表chain()
,您需要使用可迭代解包運算符( *)。此運算符解包所有輸入可迭代對象,以便chain()
可以使用它們并生成相應的迭代器。最后一步是調(diào)用list()以構(gòu)建所需的平面列表。
6.3 連接字符串 str.join()
正如您已經(jīng)看到的,sum()不連接或連接字符串。如果您需要這樣做,那么 Python
中可用的首選和最快的工具是str.join().
此方法將一系列字符串作為參數(shù)并返回一個新的連接字符串:
>>> >>> greeting = ["Hello,", "welcome to", "Real Python!"] >>> " ".join(greeting) 'Hello, welcome to Real Python!'
使用.join()是連接字符串的最有效和 Pythonic
的方式。在這里,您使用字符串列表作為參數(shù)并從輸入構(gòu)建單個字符串。請注意,.join()在連接期間使用您調(diào)用方法的字符串作為分隔符。在此示例中,您調(diào)用.join()
由單個空格字符 ( " ")
組成的字符串,因此原始字符串 fromgreeting
在最終字符串中由空格分隔。
7、結(jié)論
您現(xiàn)在可以使用 Python
的內(nèi)置函數(shù)sum()
將多個數(shù)值相加。此函數(shù)提供了一種高效、可讀且 Pythonic
的方法來解決代碼中的求和問題。如果您正在處理需要對數(shù)值求和的數(shù)學計算,那么它sum()
可以成為您的救星。
到此這篇關(guān)于Python 的 sum() Pythonic 的求和方法詳細的文章就介紹到這了,更多相關(guān)Python 的 sum() Pythonic 的求和方法內(nèi)容請搜索本站以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持本站!
版權(quán)聲明:本站文章來源標注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請保持原文完整并注明來源及原文鏈接。禁止復制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務器上建立鏡像,否則將依法追究法律責任。本站部分內(nèi)容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學習參考,不代表本站立場,如有內(nèi)容涉嫌侵權(quán),請聯(lián)系alex-e#qq.com處理。