V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
enderftt
V2EX  ›  Python

Python lambda 改写

  •  
  •   enderftt · 2021-06-23 11:21:43 +08:00 · 2874 次点击
    这是一个创建于 1250 天前的主题,其中的信息可能已经有所发展或是发生改变。

    请教各位一个问题,以下代码,怎么用 lambda 改写,我自己尝试写了之后,结果都不对

    d = [{'1':1,'2':2},{'3':3,'4':4}]
    
    def t(i):
        i['5']=5
        return i
    
    print(list(map(t,d)))
    

    我自己写的是这个

    print(list(map(lambda x:x.update({'5':5}),d)))
    

    update 返回的是 None,所以结果就是[None,None], 不知道各位大佬有其他写法吗?

    17 条回复    2021-06-23 21:03:47 +08:00
    cyrbuzz
        1
    cyrbuzz  
       2021-06-23 11:27:35 +08:00   ❤️ 2
    你这个需求直接列表推导不是更香...

    [x.update({'5':5}) for x in d]
    print(d)
    Jirajine
        2
    Jirajine  
       2021-06-23 11:27:44 +08:00 via Android
    你得用 immutable 的风格写,lambda 返回一个新的对象,而不是修改原本的对象。
    ebingtel
        3
    ebingtel  
       2021-06-23 11:31:54 +08:00
    lambada 返回一个 tuple,再根据索引 拿到对象
    no1xsyzy
        4
    no1xsyzy  
       2021-06-23 11:41:29 +08:00
    immutable 的写法,[{**x, '5': 5} for x in d]
    这样 d 完全没有被改动,但因为所有的 dict 都被复制了一份,空间效率可能有点烂,而且还反复 gc,不过考虑到增长也可能重新申请内存大概差距不大(
    要么就是 #1,改动完了仍然回头用 d,但如果 d 很长的话这个列表会占空间效率,而且我猜会被 IDE 报『可能没有效果的表达式』,可能可以写成 generator 然后用 itertools 里的东西把整个列表消耗掉( dropwhile 之类)。
    nasy
        5
    nasy  
       2021-06-23 11:43:40 +08:00
    1.
    list(map(lambda i: i | {'5': 5}, d))

    2.
    list(map(lambda i: i.update({'5': 5}) or i, d))

    3.
    from collection import ChainMap
    list(map(lambda i: ChainMap({'5': 5}, i), d))
    dongxiao
        6
    dongxiao  
       2021-06-23 11:47:39 +08:00
    ```
    print(list(map(lambda x:x.update({'5':5}) or x,d)))
    ```
    用 update 也没啥问题,比如可以用如上这种 trick 来实现
    xuboying
        7
    xuboying  
       2021-06-23 13:01:35 +08:00
    print(list(map(lambda x:{**x, '5':5},d)))
    enderftt
        8
    enderftt  
    OP
       2021-06-23 13:07:56 +08:00
    @cyrbuzz @Jirajine @ebingtel @no1xsyzy 谢谢 明白了
    enderftt
        9
    enderftt  
    OP
       2021-06-23 13:09:29 +08:00
    @nasy 这第一种写法 我这里会报错
    enderftt
        10
    enderftt  
    OP
       2021-06-23 13:09:40 +08:00
    @xuboying 谢谢
    enderftt
        11
    enderftt  
    OP
       2021-06-23 13:10:02 +08:00
    toaruScar
        12
    toaruScar  
       2021-06-23 13:18:31 +08:00
    考虑一下 ChainMap,比 update 快,还会返回东西
    https://docs.python.org/3/library/collections.html
    wangyzj
        13
    wangyzj  
       2021-06-23 13:31:08 +08:00
    print(list(map(lambda x:{**x, '5':5}, [{'1':1,'2':2},{'3':3,'4':4}])))
    imn1
        14
    imn1  
       2021-06-23 13:36:44 +08:00
    关键点是这种 obj.method(x)都是修改 obj 自身,返回 None,所以你要改写就需要返回 obj,而不是 method 的返回

    同样有 str.method/list.method 等等

    你理清这点,改写的方法就很多了
    Contextualist
        15
    Contextualist  
       2021-06-23 14:29:18 +08:00
    @enderftt
    #5 楼的第一种写法是 Python 3.9 新增的语法

    如果要兼容 Python 3.9 以下的版本,个人比较推荐 #4 楼 或 #7 楼的 immutable 写法。
    ClericPy
        16
    ClericPy  
       2021-06-23 20:59:37 +08:00
    如果你是想要返回点别的... 以前用过类似的, 那种函数返回 None 的设计一开始觉得难受, 后来也能接受

    a.update(xxx) or a
    print('hello') or result

    d = [{'1': 1, '2': 2}, {'3': 3, '4': 4}]


    def t(i):
    i['5'] = 5
    return i


    print(list(map(t, d)))
    print(list(map(lambda i: i.update({'5': 5}) or i, d)))
    # [{'1': 1, '2': 2, '5': 5}, {'3': 3, '4': 4, '5': 5}]
    # [{'1': 1, '2': 2, '5': 5}, {'3': 3, '4': 4, '5': 5}]
    no1xsyzy
        17
    no1xsyzy  
       2021-06-23 21:03:47 +08:00
    @imn1 这其实是一个语言设计的问题,不过考虑到 Python 的设计是 obj.method 是一个 wrapper,其实是个比较正常的情况。
    Ponylang 有 obj.>method(x) 会返回 obj 本身,所以 builder 类的链式调用不需要特地 return 自身,看调用方的代码也直接就清楚这是个对同一对象作各种操作。如果引入了这个语法的话,楼主直接用就成了,既不需要 hack 也不需要强行搞 immutable
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   6014 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 02:53 · PVG 10:53 · LAX 18:53 · JFK 21:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.