如何重写匿名函数?

时间:2016-05-01 17:01:23

标签: python python-3.x

我是编程和Python的新手,特别是Python3。使用在线教程我试图理解'lambda'的使用。因此,我想重写以下代码并使用其他命名函数,列表理解,字典理解或生成器。然而,与语法斗争。我无法重写.addBooks { clear: both; width: 800px; margin: 0 auto; margin-top: 10%; } .addBooks label { float: left; width: 150px; text-align: right; } .addBooks input { float: right; width: 150px; text-align: left; } .addBooks select { float: right; text-align: left; }

原始功能:

lambdas

我的调整:

import functools as ft
import itertools as it
import os
import re
import requests
import tempfile
def foo(los, n=None):
    n = n or len(los)
    h = it.takewhile(lambda p: p[0] < n, enumerate(los))
    s = sorted(h, key=lambda p: p[1])
    g = it.groupby(s, lambda p: p[1])
    return dict(it.starmap(lambda k, vs: (k, sum(map(lambda i: 1, vs))), g))

alist=[1,2,3,1,1,7,8,9,9]

print(foo(alist))

{1: 3, 2: 1, 3: 1, 7: 1, 8: 1, 9: 2}

3 个答案:

答案 0 :(得分:1)

你可以像这样重写它......

有关:

lambda args: expression_with_args

一个函数看起来像:

def func_name(args):
    return expression_with_args

E.g。

lambda p: p[0] < n

变为:

def compare_func(p, n):
    return p[0] < n

将它用作key的函数,它只需要一个参数就必须稍加修改以保存n的值:

compare_func = ft.partial(compare_func, n=n)

E.g。

lambda p: p[1]

变为:

def get_first(p):
    return p[1]

E.g。

lambda k, vs: (k, sum(map(lambda i: 1, vs)))

变为:

def as_one(i):
    return 1

def get_tuple(k, vs):
    vs_with_ones = map(as_one, vs)
    vs_sum = sum(vs_with_ones)
    return (k, vs_sum)

最后:

def foo(los, n=None):
    n = n or len(los)
    compare_func = ft.partial(compare_func, n=n)
    h = it.takewhile(compare_func, enumerate(los))
    s = sorted(h, key=get_first)
    g = it.groupby(s, get_first)
    return dict(it.starmap(get_tuple, g))

答案 1 :(得分:1)

你的第一个问题是一个简单的拼写错误。你定义的小于&#34;小于&#34;作为smaller_then_ten运行,但将其称为smaller_then_n。我打算在这里走出去,说你打算叫它smaller_than_len。接下来,您的函数smaller_then_ten根本不考虑变量n,它只使用输入列表的长度。你真正想要的是一个接受上限并返回一个函数的函数,该函数根据它检查列表的第一个元素。这样的事情。

def smaller_than_len(n):
    def f(e):
        return e[0] < n
    return f

def foo(los, n=None):
    n = n or len(los)
    h = it.takewhile(smaller_than_len(n), enumerate(los))
    ...

您最后的问题是您从sortedgroupby函数中删除了关键参数。既然你说你不想使用lambdas进行调整,你可以用名为&#34; key_func&#34;的新函数替换它们。

def smaller_than_len(n):
    def f(e):
        return e[0] < n
    return f

def key_func(e):
    return e[1]

def foo(los, n=None):
    n = n or len(los)
    h = it.takewhile(smaller_than_len(n), enumerate(los))
    s = sorted(h, key=key_func)
    g = it.groupby(s, key=key_func)
    return dict(it.starmap(lambda k, vs: (k, sum(map(lambda i: 1, vs))), g))

现在你的功能应该正常工作。

答案 2 :(得分:0)

要记住的是在某个特定环境或范围内定义的函数(通过deflambda)。在示例函数中,lambdas在foo()内定义,因此可以访问foo的局部变量(如n)。在smaller_then_ten之外定义foo时,它无法访问变量n。 Kwarrtz和Nikita都展示了解决这个问题的方法。但是,最简单的方法是在lambda所在的相同环境中定义新函数,如下所示:

def foo(los, n=None):
    def smaller_than_n(tpl):
        return tpl[0] < n

    def item1(tpl):
        return tpl[1]

    def const1(i):
        return 1

    def count(key, values):
        return key, sum(map(const1, values))

    n = n or len(los)
    h = it.takewhile(smaller_than_n, enumerate(los))
    s = sorted(h, key=item1)
    g = it.groupby(s, key=item1)
    return dict(it.starmap(count, g))

在学习Python时,请熟悉标准库。这是一个很好的资源。激起你的兴趣:foo()的前两行可以被itertools.islice取代,item1()可以被operator.itemgetter取代,整个foo函数可以被collections.Counter替换。