当前位置:  开发笔记 > 编程语言 > 正文

有用的代码使用reduce()?

如何解决《有用的代码使用reduce()?》经验,为你挑选了10个好方法。

这里有没有人有任何有用的代码在python中使用reduce()函数?除了我们在示例中看到的通常的+和*之外,还有其他代码吗?

通过GvR 参考Python 3000中的reduce()命运



1> Claudiu..:

除了+和*之外,我发现的其他用途与和和或,但现在我们已经anyall更换这些情况.

foldlfoldr在计划中提出了很多......

这是一些可爱的用法:

压平列表

目标:[[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)


为了展平列表,我更喜欢list(itertools.chain(*nested_list))
总和([[1,2,3],[4,5],[6,7,8]],[])
做一些基准测试,对于大型列表来说,"丑陋"的方式更快.`timeit.repeat('int("".join(map(str,digit_list)))',setup ='digit_list = list(d%10表示d in xrange(1,1000))',number = 1000) `timeit.repeat('reduce(lambda a,d:10*a + d,digit_list)',setup ='digit_list = list(d%10表示d in xrange(1,1000))',需要~0.09秒, number = 1000)`需要0.36秒(大约慢4倍).当列表变大时,基本乘以10变得昂贵,而对于str和连接的int保持便宜.
当然,对于小型列表(大小为10),则reduce方法快1.3倍.然而,即使在这种情况下,避免减少和做一个简单的循环甚至更快`timeit.repeat('convert_digit_list_to_int(digit_list)',setup ='digit_list = [d%10 for d in xrange(1,10)] \ndef convert_digit_list_to_int(digits):\ni = 0 \n表示数字为d:\ni = 10*i + d \n return i',number = 100000)`需要0.06秒,`timeit.repeat('reduce(lambda a, d:10*a + d,digit_list)',setup ='digit_list = list(d%10表示d in xrange(1,10))',number = 100000)`需要0.12 s并且将数字转换为str方法需要0.16秒.
它对按位运算也很有用.如果你想获取按位或一堆数字,例如,如果你需要将标志从列表转换为位掩码,该怎么办?
你正在调用最后一个简化示例吗?恕我直言,它还不错.对我来说int("".join(str(i)for i in range(1,9)))更具可读性.

2> jfs..:

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



3> jfs..:

reduce()可用于解析虚线名称(eval()使用起来太不安全):

>>> import __main__
>>> reduce(getattr, "os.path.abspath".split('.'), __main__)



4> ssoler..:

找到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 - 两个列表的交集



5> 小智..:

我认为减少是一个愚蠢的命令.因此:

reduce(lambda hold,next:hold+chr(((ord(next.upper())-65)+13)%26+65),'znlorabggbbhfrshy','')



6> mweerden..:

reduce我在代码中找到的用法涉及到我有一些逻辑表达式的类结构的情况,我需要将这些表达式对象的列表转换为表达式的连接.我已经有了一个函数make_and来创建一个给出两个表达式的连接,所以我写了reduce(make_and,l).(我知道列表不是空的;否则它就像是reduce(make_and,l,make_true).)

这正是(某些)函数式程序员喜欢reduce(或折叠函数,因为这些函数通常被称为)的原因.经常有像已经有很多二元函数+,*,min,max,级联和,在我的情况,make_andmake_or.有一个reduce使得将这些操作提升到列表(或树或任何你得到的,一般的折叠函数)是微不足道的.

当然,如果sum经常使用某些实例(例如),那么你不想继续写作reduce.但是,不是sum使用一些for循环定义,而是可以轻松地定义它reduce.

其他人提到的可读性确实是一个问题.然而,你可以争辩说,只有人们发现reduce不那么"清晰"的原因是因为它不是许多人知道和/或使用的功能.



7> jfs..:

您可以替换value = json_obj['a']['b']['c']['d']['e']为:

value = reduce(dict.__getitem__, 'abcde', json_obj)

如果您已将路径a/b/c/..作为列表.例如,使用列表中的项目更改嵌套dicts的dict中的值.



8> beardc..:

功能组合:如果您已经有一系列要连续申请的功能,例如:

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))))一种语法更具可读性和可维护性.



9> Eli Courtwri..:

@Blair Conrad:您还可以使用sum实现glob/reduce,如下所示:

files = sum([glob.glob(f) for f in args], [])

这比你的两个例子中的任何一个都要简洁,完全是Pythonic,并且仍然只有一行代码.

因此,为了回答原始问题,我个人试图避免使用reduce,因为它从来没有真正必要,我发现它不如其他方法清晰.然而,有些人习惯于减少并更喜欢列出理解(尤其是Haskell程序员).但是,如果你还没有考虑减少问题,你可能不必担心使用它.


"sum"和"reduce"都会导致二次行为.它可以在线性时间内完成:[`files = chain.from_iterable(imap(iglob,args))`](http://stackoverflow.com/questions/15995/useful-code-which-uses-reduce-in-蟒蛇/ 282678#comment18841937_16091).虽然在这种情况下可能无关紧要,因为glob()访问磁盘需要时间.

10> Jian..:

reduce 可用于支持链式属性查找:

reduce(getattr, ('request', 'user', 'email'), self)

当然,这相当于

self.request.user.email

但是当您的代码需要接受任意属性列表时,它很有用.

(处理Django模型时,任意长度的链式属性都很常见.)

推荐阅读
贾志军
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有