Python?itertools中accumulate函數(shù)用法及使用運(yùn)用詳細(xì)講解
1.1前言:
本文將詳細(xì)講解itertools中的accumulate,accumulate函數(shù)可以在前綴和中運(yùn)用,否則就需要每次移動(dòng)的時(shí)候維護(hù)一個(gè)前綴和,大家如果不知道前綴和也可以先了解一下前綴和,前綴和可以解決數(shù)組區(qū)間和查詢(xún)問(wèn)題、矩陣區(qū)域和查詢(xún)問(wèn)題、連續(xù)子數(shù)組和問(wèn)題、最大子段和問(wèn)題、最大子矩陣和問(wèn)題這里,但是如果大家不太了解前綴和也可以放心食用,因?yàn)檫\(yùn)用這個(gè)累加函數(shù)其實(shí)十分簡(jiǎn)單。
1.2定義:
itertools. accumulate(iterable[,function,*,initial = None])
創(chuàng)建一個(gè)返回累積匯總值或來(lái)自其他雙目運(yùn)算函數(shù)的累積結(jié)果的迭代器。function 默認(rèn)為加法運(yùn)算。 function 應(yīng)當(dāng)接受兩個(gè)參數(shù),即一個(gè)累積匯總值和一個(gè)來(lái)自 iterable 的值。如果提供了 initial 值,將從該值開(kāi)始累積并且輸出將比輸入可迭代對(duì)象多一個(gè)元素。
大家也可以自行實(shí)現(xiàn)前綴和,第一種是簡(jiǎn)易寫(xiě)法,這種寫(xiě)法其實(shí)已經(jīng)滿(mǎn)足很多前綴和的題目了,
pre_num = [0] #由于為了滿(mǎn)足前綴和的性質(zhì)第一個(gè)數(shù)一定要置零才能滿(mǎn)足所有的數(shù)都可以由兩個(gè)前綴和來(lái)表示 for idx,x in enumerate(nums): pre_num.append(pre_num[idx] + x)
accumulate大致相當(dāng)于:
def accumulate(iterable, function=operator.add, *, initial=None): 'Return running totals' # accumulate([1,2,3,4,5]) → 1 3 6 10 15 # accumulate([1,2,3,4,5], initial=100) → 100 101 103 106 110 115 # accumulate([1,2,3,4,5], operator.mul) → 1 2 6 24 120 iterator = iter(iterable) total = initial if initial is None: try: total = next(iterator) except StopIteration: return yield total for element in iterator: total = function(total, element) yield total
值得注意的是如下用法放回的是地址而不是元素的值
temp = itertools.accumulate([1,2,3,4,5,6], initial = 0) ##結(jié)果:<itertools.accumulate object at 0x00000193FA04D990>
如果要返回元素的值還需要如下操作:
temp = list(itertools.accumulate([1,2,3,4,5,6], initial = 0))
1.3衍生用法:
剛才我們也提到了accumulate里面有個(gè)參數(shù)是function,這個(gè)函數(shù)默認(rèn)是累加方法,但是用戶(hù)也可以自己自己設(shè)定方法,比如max , min,等其他。
data = [3, 4, 6, 2, 1, 9, 0, 7, 5, 8] list(accumulate(data, max)) # 運(yùn)行最大值 ##結(jié)果[3, 4, 6, 6, 6, 9, 9, 9, 9, 9] list(accumulate(data, operator.mul)) # 運(yùn)行乘積 ##結(jié)果[3, 12, 72, 144, 144, 1296, 0, 0, 0, 0] ##題目: 分期償還利率 5% 總額 1000 的貨款,每年還款 10 次,每次 90 update = lambda balance, payment: round(balance * 1.05) - payment list(accumulate(repeat(90, 10), update, initial=1_000)) ##結(jié)果[1000, 960, 918, 874, 828, 779, 728, 674, 618, 559, 497]
1.3Leetcode的實(shí)際運(yùn)用:
Eg1:使數(shù)組元素全部相等的最少操作次數(shù):
給你一個(gè)正整數(shù)數(shù)組 nums
。同時(shí)給你一個(gè)長(zhǎng)度為 m
的整數(shù)數(shù)組 queries
。第 i
個(gè)查詢(xún)中,你需要將 nums
中所有元素變成 queries[i]
。你可以執(zhí)行以下操作 任意 次:
- 將數(shù)組里一個(gè)元素 增大 或者 減小
1
。
請(qǐng)你返回一個(gè)長(zhǎng)度為 m
的數(shù)組 answer
,其中 answer[i]
是將 nums
中所有元素變成 queries[i]
的 最少 操作次數(shù)。
注意,每次查詢(xún)后,數(shù)組變回最開(kāi)始的值。
示例 1:
輸入:nums = [3,1,6,8], queries = [1,5]
輸出:[14,10]
解釋?zhuān)?/strong>第一個(gè)查詢(xún),我們可以執(zhí)行以下操作:
- 將 nums[0] 減小 2 次,nums = [1,1,6,8] 。
- 將 nums[2] 減小 5 次,nums = [1,1,1,8] 。
- 將 nums[3] 減小 7 次,nums = [1,1,1,1] 。
第一個(gè)查詢(xún)的總操作次數(shù)為 2 + 5 + 7 = 14 。
第二個(gè)查詢(xún),我們可以執(zhí)行以下操作:
- 將 nums[0] 增大 2 次,nums = [5,1,6,8] 。
- 將 nums[1] 增大 4 次,nums = [5,5,6,8] 。
- 將 nums[2] 減小 1 次,nums = [5,5,5,8] 。
- 將 nums[3] 減小 3 次,nums = [5,5,5,5] 。
第二個(gè)查詢(xún)的總操作次數(shù)為 2 + 4 + 1 + 3 = 10 。
#題解參考萬(wàn)能的靈神:
本題采用數(shù)組排序后,二分找q的位置,其中藍(lán)色的面積+綠色的面積即為答案,并且本題可以采用前綴和優(yōu)化:
class Solution: def minOperations(self, nums: List[int], queries: List[int]) -> List[int]: nums.sort() n = len(nums) s = list(accumulate(nums,initial = 0)) ##前綴和 ans = [] for q in queries: j = bisect_left(nums, q) left = q * j - s[j] #藍(lán)色面積 right = s[n] - s[j] - q*(n - j) #綠色的面積 ans.append(left + right) return ans
Eg2:執(zhí)行操作頻率分?jǐn)?shù)最大:(注意本題和上題十分類(lèi)似,只是本題是前綴和+滑動(dòng)窗口)
給你一個(gè)下標(biāo)從 0 開(kāi)始的整數(shù)數(shù)組 nums
和一個(gè)整數(shù) k
。你可以對(duì)數(shù)組執(zhí)行 至多 k
次操作:
- 從數(shù)組中選擇一個(gè)下標(biāo)
i
,將nums[i]
增加 或者 減少1
。 - 最終數(shù)組的頻率分?jǐn)?shù)定義為數(shù)組中眾數(shù)的 頻率 。
請(qǐng)你返回你可以得到的 最大 頻率分?jǐn)?shù)。眾數(shù)指的是數(shù)組中出現(xiàn)次數(shù)最多的數(shù)。一個(gè)元素的頻率指的是數(shù)組中這個(gè)元素的出現(xiàn)次數(shù)。
示例 1:
輸入:nums = [1,2,6,4], k = 3
輸出:3
解釋?zhuān)?/strong>我們可以對(duì)數(shù)組執(zhí)行以下操作:
- 選擇 i = 0 ,將 nums[0] 增加 1 。得到數(shù)組 [2,2,6,4] 。
- 選擇 i = 3 ,將 nums[3] 減少 1 ,得到數(shù)組 [2,2,6,3] 。
- 選擇 i = 3 ,將 nums[3] 減少 1 ,得到數(shù)組 [2,2,6,2] 。
元素 2 是最終數(shù)組中的眾數(shù),出現(xiàn)了 3 次,所以頻率分?jǐn)?shù)為 3 。3 是所有可行方案里的最大頻率分?jǐn)?shù)。l
靈神題解:數(shù)組排序后,要變成一樣的數(shù)必然在一個(gè)連續(xù)子數(shù)組中,那么用滑動(dòng)窗口來(lái)做,枚舉子數(shù)組的右端點(diǎn) right,然后維護(hù)子數(shù)組的左端點(diǎn) left。根據(jù)中位數(shù)貪心,最優(yōu)做法是把子數(shù)組內(nèi)的元素都變成子數(shù)組的中位數(shù),操作次數(shù)如果超過(guò) k,就必須移動(dòng)左端點(diǎn)。求出數(shù)組的前綴和,就可以 O(1) 算出操作次數(shù)了,
from itertools import accumulate class Solution: def maxFrequencyScore(self, nums: List[int], k: int) -> int: #前綴和的知識(shí),注意前綴和s[0] == 0 這樣定義有一個(gè)好處就是任意子數(shù)組包括前綴哦都可以表示為兩個(gè)前綴和的差 #中位數(shù)貪心,將所有元素變?yōu)閚ums的中位數(shù)是最優(yōu) nums.sort()##最開(kāi)始忘了要排序 pre_sum = list(accumulate(nums, initial = 0)) #由于第一個(gè)數(shù)字是零所以整個(gè)長(zhǎng)度就是n + 1 def distance_sum(left , right) -> int: mid = ( right + left ) // 2 left_sum = nums[mid] * (mid - left) - (pre_sum[mid] - pre_sum[left]) right_sum = pre_sum[right+1] - pre_sum[mid+1] - (right - mid) * nums[mid] return left_sum + right_sum left = ans = 0 #滑動(dòng)窗口 for right in range(len(nums)): while distance_sum(left,right) > k : left += 1 ans = max(ans,right - left + 1) return ans
總結(jié)
到此這篇關(guān)于Python itertools中accumulate函數(shù)用法及使用運(yùn)用詳細(xì)講解的文章就介紹到這了,更多相關(guān)Python itertools中accumulate函數(shù)用法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python+OpenCV之形態(tài)學(xué)操作詳解
這篇文章主要為大家詳細(xì)介紹了Python?OpenCV中的形態(tài)學(xué)操作(開(kāi)運(yùn)算、閉運(yùn)算)的實(shí)現(xiàn),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2022-09-09python 普通克里金(Kriging)法的實(shí)現(xiàn)
這篇文章主要介紹了python 普通克里金(Kriging)法的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12用python的seaborn畫(huà)數(shù)值箱型圖
大家好,本篇文章主要講的是用python的seaborn畫(huà)數(shù)值箱型圖,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話(huà)記得收藏一下2022-01-01python中strip(),lstrip(),rstrip()函數(shù)的使用講解
這篇文章主要介紹了python中strip(),lstrip(),rstrip()函數(shù)的使用講解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11Python?中的反轉(zhuǎn)字符串reversed(),切片
這篇文章主要介紹了Python?中的反轉(zhuǎn)字符串reversed(),切片?,以相反的順序反轉(zhuǎn)和處理字符串可能是編程中的一項(xiàng)常見(jiàn)任務(wù)。Python?提供了一組工具和技術(shù),可以幫助我們快速有效地執(zhí)行字符串反轉(zhuǎn),下面來(lái)看看具體內(nèi)容吧2021-12-12詳解在Python程序中解析并修改XML內(nèi)容的方法
這篇文章主要介紹了在Python程序中解析并修改XML內(nèi)容的方法,依賴(lài)于解析成樹(shù)狀結(jié)構(gòu)后的節(jié)點(diǎn)進(jìn)行修改,需要的朋友可以參考下2015-11-11Python實(shí)現(xiàn)朗讀在線(xiàn)音頻和本地音頻
在日常的Python軟件開(kāi)發(fā)中,我們經(jīng)常會(huì)遇到一個(gè)非常重要的功能需求——讓程序能夠讀取并顯示文本內(nèi)容,下面我們就來(lái)學(xué)習(xí)一下Python實(shí)現(xiàn)朗讀音頻的具體操作吧2024-03-03python標(biāo)準(zhǔn)庫(kù)學(xué)習(xí)之sys模塊詳解
sys模塊是最常用的和python解釋器交互的模塊,sys模塊可供訪(fǎng)問(wèn)由解釋器(interpreter)使用或維護(hù)的變量和與解釋器進(jìn)行交互的函數(shù),下面這篇文章主要給大家介紹了關(guān)于python標(biāo)準(zhǔn)庫(kù)學(xué)習(xí)之sys模塊的相關(guān)資料,需要的朋友可以參考下2022-08-08Python簡(jiǎn)單實(shí)現(xiàn)的代理服務(wù)器端口映射功能示例
這篇文章主要介紹了Python簡(jiǎn)單實(shí)現(xiàn)的代理服務(wù)器端口映射功能,結(jié)合實(shí)例形式分析了Python模擬服務(wù)器、代理服務(wù)器及客戶(hù)端訪(fǎng)問(wèn)的相關(guān)操作技巧,需要的朋友可以參考下2018-04-04python實(shí)現(xiàn)爬取千萬(wàn)淘寶商品的方法
這篇文章主要介紹了python實(shí)現(xiàn)爬取千萬(wàn)淘寶商品的方法,涉及Python頁(yè)面抓取的相關(guān)技巧,需要的朋友可以參考下2015-06-06