Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/295.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,这里有人有在python中使用reduce()函数的有用代码吗?除了示例中常见的+和*之外,还有其他代码吗 按GvR参考不确定这是否是您想要的,但您可以 按照谷歌代码搜索的链接进行搜索 乍一看,以下项目使用reduce() 莫因 佐佩 数字的 科学巨蟒 但这些都是巨大的项目,因此并不令人惊讶 reduce的功能可以使用函数递归来实现,我想Guido认为函数递归更明确 更新: 由于谷歌的代码搜索在2012年1月15日停止,除了恢复常规谷歌搜索之外,还有一种叫做“看起来很有希望”的东西。在回答这

这里有人有在python中使用reduce()函数的有用代码吗?除了示例中常见的+和*之外,还有其他代码吗


按GvR参考不确定这是否是您想要的,但您可以

按照谷歌代码搜索的链接进行搜索

乍一看,以下项目使用
reduce()

  • 莫因
  • 佐佩
  • 数字的
  • 科学巨蟒
但这些都是巨大的项目,因此并不令人惊讶


reduce的功能可以使用函数递归来实现,我想Guido认为函数递归更明确

更新:

由于谷歌的代码搜索在2012年1月15日停止,除了恢复常规谷歌搜索之外,还有一种叫做“看起来很有希望”的东西。在回答这个(非公开)问题时提到了许多其他资源

更新2(2017年5月29日):


Python示例(在开源代码中)的一个很好的源代码是。

我有一个旧的Python实现,它使用reduce和glob模块构建要处理的文件列表:

files = []
files.extend(reduce(lambda x, y: x + y, map(glob.glob, args)))
我当时觉得它很方便,但其实没有必要,因为类似的东西同样好,而且可能更可读

files = []
for f in args:
    files.extend(glob.glob(f))

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

files = sum([glob.glob(f) for f in args], [])
这比您的两个示例中的任何一个都要简单,完全是python式的,并且仍然只有一行代码


所以为了回答最初的问题,我个人尽量避免使用reduce,因为它从来没有真正的必要,而且我发现它没有其他方法那么清晰。然而,有些人已经习惯了reduce,他们更喜欢reduce而不是list comprehension(尤其是Haskell程序员)。但是,如果您还没有考虑reduce方面的问题,那么您可能不需要担心如何使用它。

在对我的代码进行grepping之后,似乎我使用reduce的唯一目的就是计算阶乘:

reduce(operator.mul, xrange(1, x+1) or (1,))

我在代码中发现的
reduce
的用法涉及到这样一种情况:我有一些逻辑表达式的类结构,需要将这些表达式对象的列表转换为表达式的连接。我已经有了一个函数
make\u和
来创建给定两个表达式的连词,所以我编写了
reduce(make\u和,l)
。(我知道列表不是空的;否则它会像
reduce(make_和,l,make_true)

这正是(某些)函数式程序员,如
reduce
(或折叠函数,通常称为折叠函数)的原因。通常已经有很多二进制函数,如
+
*
min
max
,串联,在我的例子中还有
make\u和
make\u或
。拥有一个
reduce
使得将这些操作提升到列表(或树或任何你得到的东西,通常是折叠函数)变得很简单

当然,如果经常使用某些实例化(例如
sum
),那么您不希望继续编写
reduce
。但是,与使用某些for循环定义
sum
不同,您可以使用
reduce
轻松定义它


正如其他人提到的那样,可读性确实是一个问题。然而,你可能会争辩说,人们认为
reduce
不那么“清晰”的唯一原因是因为它不是很多人知道和/或使用的函数。

除了+和*之外,我发现它的其他用法是and和or,但现在我们有
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(lambda a,d: 10*a+d, [1,2,3,4,5,6,7,8], 0)
reduce()
可用于查找:

例如:

>>> lcm(100, 23, 98)
112700
>>> lcm(*range(1, 20))
232792560
reduce()
可用于解析虚线名称(其中
eval()
太不安全,无法使用):

导入主__ >>>reduce(getattr,“os.path.abspath”.split('.'),\uuu main\uuuu)
我正在为一种语言编写一个合成函数,因此我使用reduce和apply操作符构造合成函数

简言之,compose将一系列函数组合成一个函数。如果我有一个分阶段应用的复杂操作,我想把它放在一起,如下所示:

complexop = compose(stage4, stage3, stage2, stage1)
这样,我就可以将其应用于如下表达式:

complexop(expression)
我希望它相当于:

stage4(stage3(stage2(stage1(expression))))
现在,要构建我的内部对象,我希望它说:

Lambda([Symbol('x')], Apply(stage4, Apply(stage3, Apply(stage2, Apply(stage1, Symbol('x'))))))
(Lambda类构建用户定义的函数,Apply构建函数应用程序。)

现在,不幸的是,用错误的方法减少折叠,所以我使用了,大致如下:

reduce(lambda x,y: Apply(y, x), reversed(args + [Symbol('x')]))
要想知道reduce产生了什么,请在REPL中尝试以下方法:

reduce(lambda x, y: (x, y), range(1, 11))
reduce(lambda x, y: (y, x), reversed(range(1, 11)))

查找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:

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

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

如果您已经将路径
a/b/c/.
作为列表。例如,.

我认为reduce是一个愚蠢的命令。因此:

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

Reduce不限于标量操作;它也可以用来把东西分类到桶里。(这是我最常使用的reduce)

设想一种情况,在这种情况下,您有一个对象列表,并且希望根据对象中平铺存储的属性按层次重新组织它。在下面的示例中,我使用
articles
函数生成了一个与XML编码的报纸中的文章相关的元数据对象列表
articles
生成一个XML元素列表,然后逐个映射,生成包含有关这些元素的一些有趣信息的对象。
value = reduce(dict.__getitem__, 'abcde', json_obj)
reduce(lambda hold,next:hold+chr(((ord(next.upper())-65)+13)%26+65),'znlorabggbbhfrshy','')
from lxml import etree
from Reader import Reader

class IssueReader(Reader):
    def articles(self):
        arts = self.q('//div3')  # inherited ... runs an xpath query against the issue
        subsection = etree.XPath('./ancestor::div2/@type')
        section = etree.XPath('./ancestor::div1/@type')
        header_text = etree.XPath('./head//text()')
        return map(lambda art: {
            'text_id': self.id,
            'path': self.getpath(art)[0],
            'subsection': (subsection(art)[0] or '[none]'),
            'section': (section(art)[0] or '[none]'),
            'headline': (''.join(header_text(art)) or '[none]')
        }, arts)

    def by_section(self):
        arts = self.articles()

        def extract(acc, art):  # acc for accumulator
            section = acc.get(art['section'], False)
            if section:
                subsection = acc.get(art['subsection'], False)
                if subsection:
                    subsection.append(art)
                else:
                    section[art['subsection']] = [art]
            else:
                acc[art['section']] = {art['subsection']: [art]}
            return acc

        return reduce(extract, arts, {})
reduce(lambda x,y: x if x[2] > y[2] else y,[[1,2,3,4],[5,2,5,7],[1,6,0,2]])
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'
from datetime import date, timedelta


def checked(d1, d2):
    """
    We assume the date list is sorted.
    If d2 & d1 are different by 1, everything up to d2 is consecutive, so d2
    can advance to the next reduction.
    If d2 & d1 are not different by 1, returning d1 - 1 for the next reduction
    will guarantee the result produced by reduce() to be something other than
    the last date in the sorted date list.

    Definition 1: 1/1/14, 1/2/14, 1/2/14, 1/3/14 is consider consecutive
    Definition 2: 1/1/14, 1/2/14, 1/2/14, 1/3/14 is consider not consecutive

    """
    #if (d2 - d1).days == 1 or (d2 - d1).days == 0:  # for Definition 1
    if (d2 - d1).days == 1:                          # for Definition 2
        return d2
    else:
        return d1 + timedelta(days=-1)

# datelist = [date(2014, 1, 1), date(2014, 1, 3),
#             date(2013, 12, 31), date(2013, 12, 30)]

# datelist = [date(2014, 2, 19), date(2014, 2, 19), date(2014, 2, 20),
#             date(2014, 2, 21), date(2014, 2, 22)]

datelist = [date(2014, 2, 19), date(2014, 2, 21),
            date(2014, 2, 22), date(2014, 2, 20)]

datelist.sort()

if datelist[-1] == reduce(checked, datelist):
    print "dates are consecutive"
else:
    print "dates are not consecutive"
from collections import Counter

stat2011 = Counter({"January": 12, "February": 20, "March": 50, "April": 70, "May": 15,
           "June": 35, "July": 30, "August": 15, "September": 20, "October": 60,
           "November": 13, "December": 50})

stat2012 = Counter({"January": 36, "February": 15, "March": 50, "April": 10, "May": 90,
           "June": 25, "July": 35, "August": 15, "September": 20, "October": 30,
           "November": 10, "December": 25})

stat2013 = Counter({"January": 10, "February": 60, "March": 90, "April": 10, "May": 80,
           "June": 50, "July": 30, "August": 15, "September": 20, "October": 75,
           "November": 60, "December": 15})

stat_list = [stat2011, stat2012, stat2013]

print reduce(lambda x, y: x & y, stat_list)     # MIN
print reduce(lambda x, y: x | y, stat_list)     # MAX
import os

files = [
    # full filenames
    "var/log/apache/errors.log",
    "home/kane/images/avatars/crusader.png",
    "home/jane/documents/diary.txt",
    "home/kane/images/selfie.jpg",
    "var/log/abc.txt",
    "home/kane/.vimrc",
    "home/kane/images/avatars/paladin.png",
]

# unfolding of plain filiname list to file-tree
fs_tree = ({}, # dict of folders
           []) # list of files
for full_name in files:
    path, fn = os.path.split(full_name)
    reduce(
        # this fucction walks deep into path
        # and creates placeholders for subfolders
        lambda d, k: d[0].setdefault(k,         # walk deep
                                     ({}, [])), # or create subfolder storage
        path.split(os.path.sep),
        fs_tree
    )[1].append(fn)

print fs_tree
#({'home': (
#    {'jane': (
#        {'documents': (
#           {},
#           ['diary.txt']
#        )},
#        []
#    ),
#    'kane': (
#       {'images': (
#          {'avatars': (
#             {},
#             ['crusader.png',
#             'paladin.png']
#          )},
#          ['selfie.jpg']
#       )},
#       ['.vimrc']
#    )},
#    []
#  ),
#  'var': (
#     {'log': (
#         {'apache': (
#            {},
#            ['errors.log']
#         )},
#         ['abc.txt']
#     )},
#     [])
#},
#[])
class Exon:
    def __init__(self):
        ...
    def __and__(self,other):
        ...
        length = self.length + other.length  # (e.g.)
        return self.__class__(...length,...)
intersection = reduce(lambda x,y: x&y, exons)
reduce(getattr, ('request', 'user', 'email'), self)
self.request.user.email
>>> reduce(operator.or_, ({1}, {1, 2}, {1, 3}))  # union
{1, 2, 3}
>>> reduce(operator.and_, ({1}, {1, 2}, {1, 3}))  # intersection
{1}
>>> any((True, False, True))
True
def dump(fname,iterable):
  with open(fname,'w') as f:
    reduce(lambda x, y: f.write(unicode(y,'utf-8')), iterable)
reduce(lambda acc, elem: acc[:-1] + [acc[-1] + elem] if elem == "\n" else acc + [elem], re.split("(\n)", "a\nb\nc\n"), [])
['a\n', 'b\n', 'c\n', '']
vectors = (self.column_vector(getattr(self.table.c, column_name))
           for column_name in self.indexed_columns)
concatenated = reduce(lambda x, y: x.op('||')(y), vectors)
compiled = concatenated.compile(self.conn)