这里有没有人有任何有用的代码在python中使用reduce()函数?除了我们在示例中看到的通常的+和*之外,还有其他代码吗?
通过GvR 参考Python 3000中的reduce()命运
除了+和*之外,我发现的其他用途与和和或,但现在我们已经any
和all
更换这些情况.
foldl
并foldr
在计划中提出了很多......
这是一些可爱的用法:
压平列表
目标:[[1, 2, 3], [4, 5], [6, 7, 8]]
变成[1, 2, 3, 4, 5, 6, 7, 8]
.
reduce(list.__add__, [[1, 2, 3], [4, 5], [6, 7, 8]], [])
数字的数字列表
目标:[1, 2, 3, 4, 5, 6, 7, 8]
变成12345678
.
丑陋,缓慢的方式:
int("".join(map(str, [1,2,3,4,5,6,7,8])))
漂亮的reduce
方式:
reduce(lambda a,d: 10*a+d, [1,2,3,4,5,6,7,8], 0)
reduce()
可用于查找3个或更多数字的最小公倍数:
#!/usr/bin/env python from fractions import gcd from functools import reduce def lcm(*args): return reduce(lambda a,b: a * b // gcd(a, b), args)
例:
>>> lcm(100, 23, 98) 112700 >>> lcm(*range(1, 20)) 232792560
reduce()
可用于解析虚线名称(eval()
使用起来太不安全):
>>> import __main__ >>> reduce(getattr, "os.path.abspath".split('.'), __main__)
找到N个给定列表的交集:
input_list = [[1, 2, 3, 4, 5], [2, 3, 4, 5, 6], [3, 4, 5, 6, 7]] result = reduce(set.intersection, map(set, input_list))
收益:
result = set([3, 4, 5])
via:Python - 两个列表的交集
我认为减少是一个愚蠢的命令.因此:
reduce(lambda hold,next:hold+chr(((ord(next.upper())-65)+13)%26+65),'znlorabggbbhfrshy','')
reduce
我在代码中找到的用法涉及到我有一些逻辑表达式的类结构的情况,我需要将这些表达式对象的列表转换为表达式的连接.我已经有了一个函数make_and
来创建一个给出两个表达式的连接,所以我写了reduce(make_and,l)
.(我知道列表不是空的;否则它就像是reduce(make_and,l,make_true)
.)
这正是(某些)函数式程序员喜欢reduce
(或折叠函数,因为这些函数通常被称为)的原因.经常有像已经有很多二元函数+
,*
,min
,max
,级联和,在我的情况,make_and
和make_or
.有一个reduce
使得将这些操作提升到列表(或树或任何你得到的,一般的折叠函数)是微不足道的.
当然,如果sum
经常使用某些实例(例如),那么你不想继续写作reduce
.但是,不是sum
使用一些for循环定义,而是可以轻松地定义它reduce
.
其他人提到的可读性确实是一个问题.然而,你可以争辩说,只有人们发现reduce
不那么"清晰"的原因是因为它不是许多人知道和/或使用的功能.
您可以替换value = json_obj['a']['b']['c']['d']['e']
为:
value = reduce(dict.__getitem__, 'abcde', json_obj)
如果您已将路径a/b/c/..
作为列表.例如,使用列表中的项目更改嵌套dicts的dict中的值.
功能组合:如果您已经有一系列要连续申请的功能,例如:
color = lambda x: x.replace('brown', 'blue') speed = lambda x: x.replace('quick', 'slow') work = lambda x: x.replace('lazy', 'industrious') fs = [str.lower, color, speed, work, str.title]
然后你可以连续应用它们:
>>> call = lambda s, func: func(s) >>> s = "The Quick Brown Fox Jumps Over the Lazy Dog" >>> reduce(call, fs, s) 'The Slow Blue Fox Jumps Over The Industrious Dog'
在这种情况下,方法链可能更具可读性.但有时这是不可能的,这种组合可能比f1(f2(f3(f4(x))))
一种语法更具可读性和可维护性.
@Blair Conrad:您还可以使用sum实现glob/reduce,如下所示:
files = sum([glob.glob(f) for f in args], [])
这比你的两个例子中的任何一个都要简洁,完全是Pythonic,并且仍然只有一行代码.
因此,为了回答原始问题,我个人试图避免使用reduce,因为它从来没有真正必要,我发现它不如其他方法清晰.然而,有些人习惯于减少并更喜欢列出理解(尤其是Haskell程序员).但是,如果你还没有考虑减少问题,你可能不必担心使用它.
reduce
可用于支持链式属性查找:
reduce(getattr, ('request', 'user', 'email'), self)
当然,这相当于
self.request.user.email
但是当您的代码需要接受任意属性列表时,它很有用.
(处理Django模型时,任意长度的链式属性都很常见.)