Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么reduce函数的初始值不是强制性的?_Python_Functional Programming - Fatal编程技术网

Python 为什么reduce函数的初始值不是强制性的?

Python 为什么reduce函数的初始值不是强制性的?,python,functional-programming,Python,Functional Programming,在haskell中,foldl运算符的初始值显然是强制性的 Prelude> foldl (+) 0 [1] 1 Prelude> foldl (+) 0 [] 0 Prelude> :t foldl (a -> b -> a) -> a -> [b] -> a 但是在reduce函数(或functools.reduce)中,初始值是可选的 reduce(function, sequence[, initial]) -> value 唯一

在haskell中,
foldl
运算符的初始值显然是强制性的

Prelude> foldl (+) 0 [1]
1
Prelude> foldl (+) 0 []
0
Prelude> :t foldl
(a -> b -> a) -> a -> [b] -> a
但是在reduce函数(或
functools.reduce
)中,初始值是可选的

reduce(function, sequence[, initial]) -> value
唯一需要初始值的时间是序列为空时。这与哈斯克尔的行为一致。python中的
reduce
是否假定如果序列大小为1;然后它在内部处理这些角落案例

>> reduce(operator.sub, [1])
1
>> reduce(operator.mul, [1])
1
>> reduce(operator.add, [1])
1
从:

如果未给出初始值设定项,并且iterable只包含一项,则 第一项被退回


我还想就此发表评论:

唯一需要初始值的时间是序列为 空的


这并不完全正确。在折叠操作中,您通常假定您有一个较早的结果要处理。如果折叠操作将元素附加到列表中,则初始元素可以是空列表,因此可以向该列表中添加元素。更一般地说,当函数的返回类型与列表中元素的类型不同时,始终需要初始值。

回想一下,在Haskell中有两个版本的折叠-一个接受某个结果类型的种子,另一个假设种子是序列的第一个元素

foldr :: (a -> b -> b) -> b -> [a] -> b
foldr k z = go
        where
            go []     = z
            go (y:ys) = y `k` go ys

foldr
使用序列的初始元素作为第一个状态


还有一个重要的区别:通过使用序列的第一个元素作为输入状态,
foldr1
被约束为返回与输入列表相同类型的数组
foldr
但是可以返回一些不同的类型。

在Haskell中,
foldl1
也不需要初始值。请注意,最后一行的拼写更像Python:
sum([1])
。其他情况是有争议的(我的意思是,你可以做
a[0]+sum(-b代表a[1:])
,但我想大多数不会),但通常认为最好是显式地写出累加器循环。Python并不是真正的函数式语言,它是一种具有一些函数特性的OO语言。
foldr1 :: (a -> a -> a) -> [a] -> a
foldr1 _ [x]            =  x
foldr1 f (x:xs)         =  f x (foldr1 f xs)
foldr1 _ []             =  errorEmptyList "foldr1"