关于lambda在defaultdict中的用法
2266查看
LOU3267761252
2017-12-28 10:42

在#绘制水平分割线中,separator = defaultdict(lambda: line)中

问题1:我接触的lambda用法都是为了简单声明函数,这么用我不知道代表什么

问题2:separator = defaultdict(lambda: line) 这种声明方式能不能用更基础的语句写出来?觉得这样能方便我理解一下

全部回复(4)
石头山
2017-12-29 03:24

抱歉,这个代码我也没有完全理解,结合上下文也没有看明白为什么这里要用到 defaultdict。这里的 lambda 的作用就是提供一个返回 line 的匿名函数,但 line 的值是固定的。所以调用 separator[0] 就会得到 line 的值,将后续的使用 separator 的地方直接换成 line 试试,应该启动是没有问题的,但执行可能会有bug。

defaultdict 是 collections 中比较难理解的一个,关于 defaultdict 可以看这篇文章,是我感觉讲得比较清楚的一篇: http://kodango.com/understand-defaultdict-in-python

回复
一股重口味
2018-03-16 06:45

感觉作者在这里的写法复杂了,我直接把draw_hor_separator()函数改成

def draw_hor_separator():
    line = ('+------' * self.width + '+')
    cast(line)
copy

简单测试下,也是没有问题的 另外原来的lambda是为了配合defaultdict,因为defaultdict 的第一个参数必须callable 虽说在这里用defaultdict没必要就是了...

回复
LOU2331108277
2019-07-11 11:18

我研究了很久,发现作者写这个完全可以改成你这种形式,我真没搞懂counter什么,搞这么复杂…… 完全是炫技装逼用的。

回复
LOU2331108277
2019-07-11 11:55

我来解释一下楼主的疑问。首先按照一股重口味的做法改没毛病。然后你的问题是为啥要lambda,这个是在作者使用defaultdict类导致的。

先讲defaultdict这个类。我觉得用的地方不多。主要是为了合并“当字典里的键不存在时新建一个带默认值的键”和“运用新建的键加以计算”这两步存在的。 http://kodango.com/understand-defaultdict-in-python 参考这个讲解,可以发现,我们完全可以通过检查键是否存在,不存在新建该键并且赋值的方式来达到defaultdict的目的。

from collections import defaultdict

strings = ('puppy', 'kitten', 'puppy', 'puppy',
           'weasel', 'puppy', 'kitten', 'puppy')
counts = defaultdict(lambda: 0)  # 使用lambda来定义简单的函数

for s in strings:
    counts[s] += 1
copy

这是统计stirngs里面字符串重复次数的,假如没有defaultdict,我们就只能类似这样:

strings = ('puppy', 'kitten', 'puppy', 'puppy',
           'weasel', 'puppy', 'kitten', 'puppy')
counts = {}

for kw in strings:
    if kw not in counts:
        counts[kw] = 1
    else:
        counts[kw] += 1
copy

复杂了几步。利用defaultdict,我们可以把新建键和运算合并到一步。方便了一点(这是得多纠结) 需要注意的是,defaultdict需要我们传入数据类型,所以变量是不能传入的。 回到作者的代码,line这个变量是没办法传入的,需要动点手脚,以函数的形式传入。这时候就只能使用lambda:line来传入。此时题主的问题已经解决。lambda:line 结果上等价于line ------题外话 那为啥会有counter的出现呢?我猜测,由于defaultdict这个也还是需要键的输入,为了做到自动化,最简单的方法莫过于 += 1了,因此搞了个counter出来.

回复
你的回复