假設(shè)有一個(gè)函數(shù),這個(gè)函數(shù)需要接收4個(gè)參數(shù),并返回這4個(gè)參數(shù)的和:
def sum_four(a, b, c, d):
return a + b + c + d
如果需要固定最后前三個(gè)參數(shù),僅改變最后一個(gè)參數(shù)的值,這時(shí)候可能需要這么調(diào)用:
>> > a, b, c = 1, 2, 3
>> > sum_four(a=a, b=b, c=c, d=1)
7
>> > sum_four(a=a, b=b, c=c, d=2)
8
>> > sum_four(a=a, b=b, c=c, d=3)
9
>> > sum_four(a=a, b=b, c=c, d=4)
10
這樣寫(xiě)實(shí)在是太丑了,如果用 Map 函數(shù),是否能簡(jiǎn)化代碼?
答案是肯定的,但是Map函數(shù)【一般】只能接受單一元素,如果你強(qiáng)行使用的話,它會(huì)報(bào)這樣的錯(cuò):
> >> list(map(sum_four, [(1, 2, 3, 4)]))
Traceback (most recent call last):
File "< stdin >", line 1, in < module >
TypeError: sum_four() missing 3 required positional arguments: 'b', 'c', and 'd'
怎么解決?
方案1: itertools.starmap
可以使用 itertools 的函數(shù) starmap 替換Map.
它與Map不同,允許接受一個(gè)元組作為傳入sum_four的參數(shù)。
>> > import itertools
>> > list(itertools.starmap(sum_four, [(1, 2, 3, 4)]))
[10]
非常棒,這樣的話,上述問(wèn)題就可以使用starmap函數(shù)解決:
>> > import itertools
>> > ds = [1, 2, 3, 4]
>> > items = ((a, b, c, d) for d in ds)
>> > list(items)
[(1, 2, 3, 1), (1, 2, 3, 2), (1, 2, 3, 3), (1, 2, 3, 4)]
>> > list(itertools.starmap(sum_four, items))
[7, 8, 9, 10]
請(qǐng)注意 items 是一個(gè)生成器,這是為了避免 items 過(guò)大導(dǎo)致內(nèi)存消耗量過(guò)大。平時(shí)開(kāi)發(fā)的時(shí)候注意這些細(xì)節(jié),能夠使你和普通的開(kāi)發(fā)者拉開(kāi)差距。
方案2: functools.partial
第二種解決方案是使用 partial 函數(shù)固定前三個(gè)參數(shù)。
根據(jù)文檔,partial
將“凍結(jié)”函數(shù)的參數(shù)的某些部分,從而生成簡(jiǎn)化版的函數(shù)。
因此上述問(wèn)題的解決方案就是:
>> > import functools
>> > partial_sum_four = functools.partial(sum_four, a, b, c)
>> > partial_sum_four(3)
9
>> > # 這樣就可以使用map函數(shù)了:
>> > list(map(partial_sum_four, ds))
[7, 8, 9, 10]
方案3: itertools.repeat()
事實(shí)上,Map 函數(shù)是允許傳遞可迭代參數(shù)的,但是有一個(gè)有趣的特點(diǎn),他會(huì)用每個(gè)可迭代對(duì)象里的項(xiàng)作為傳入函數(shù)的不同參數(shù)。這樣說(shuō)可能太過(guò)于抽象了,來(lái)看看實(shí)際的例子:
> >> list(map(sum_four, [1,1,1,1], [2,2,2,2], [3,3,3,3], [1,2,3,4]))
[7, 8, 9, 10]
明顯,每次都使用了不同數(shù)組中對(duì)應(yīng)下標(biāo)的項(xiàng)傳入函數(shù)進(jìn)行計(jì)算。
這樣,我們可以使用這個(gè)特點(diǎn)進(jìn)行優(yōu)化。
itertools.repeat() 函數(shù)能夠根據(jù)參數(shù)產(chǎn)生一個(gè)迭代器,該迭代器一次又一次返回對(duì)象。不指定times參數(shù),它將無(wú)限期運(yùn)行。
而 Map 函數(shù)會(huì)在最短的可迭代對(duì)象被迭代完后,就會(huì)自動(dòng)停止運(yùn)行。
結(jié)合這兩個(gè)特點(diǎn),上述問(wèn)題的解決方案就出來(lái)了:
>> > import itertools
>> > list(map(sum_four, itertools.repeat(a), itertools.repeat(b), itertools.repeat(c), ds))
[7, 8, 9, 10]
這招非常巧妙,缺點(diǎn)是能讀懂的人不多。不過(guò)沒(méi)關(guān)系,計(jì)算機(jī)世界中某些東西知道就好,你并不一定需要去使用它。
-
參數(shù)
+關(guān)注
關(guān)注
11文章
1835瀏覽量
32227 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4331瀏覽量
62631 -
python
+關(guān)注
關(guān)注
56文章
4797瀏覽量
84694 -
數(shù)組
+關(guān)注
關(guān)注
1文章
417瀏覽量
25947
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論