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
Macv1994
V2EX  ›  Python

关于字典的操作,求一个较好的解决方案

  •  
  •   Macv1994 ·
    weijiang1994 · 2021-08-13 12:32:33 +08:00 · 1841 次点击
    这是一个创建于 958 天前的主题,其中的信息可能已经有所发展或是发生改变。

    需求是将两个列表合并,如果 err_data 中的 id 与 new_data 中的 id 重复,那么就把 err_data 中的项去掉,各位彦祖,合并后的顺序无所谓,求一个较好的方法。

    err_data = [
        {'id': 1, 'data': 23},
        {'id': 2, 'data': 24},
        {'id': 3, 'data': 25},
        {'id': 4, 'data': 222},
        {'id': 5, 'data': 134},
        {'id': 6, 'data': 255}
    ]
    
    new_data = [
        {'id': 1, 'data': 345},
        {'id': 2, 'data': 124},
        {'id': 28, 'data': 124},
        {'id': 29, 'data': 124},
        {'id': 30, 'data': 124}
    ]
    
    # 需求是将两个列表合并,如果 err_data 中的 id 与 new_data 中的 id 重复,那么就把 err_data 中的项去掉,
    # new_data + err_data 的结果如下
    result = [
        {'id': 3, 'data': 25},
        {'id': 4, 'data': 222},
        {'id': 5, 'data': 134},
        {'id': 6, 'data': 255},
        {'id': 28, 'data': 124},
        {'id': 29, 'data': 124},
        {'id': 30, 'data': 124},
        {'id': 1, 'data': 345},
        {'id': 2, 'data': 124},
    ]
    
    
    11 条回复    2021-08-15 03:15:55 +08:00
    kebyn
        1
    kebyn  
       2021-08-13 13:41:17 +08:00
    no1xsyzy
        2
    no1xsyzy  
       2021-08-13 14:10:00 +08:00
    [*{**{t['id']:t for t in err_data}, **{t['id']:t for t in new_data}}.values()]
    yuruizhe
        3
    yuruizhe  
       2021-08-13 14:29:52 +08:00
    from operator import itemgetter

    err_data, new_data = {itemgetter('id')(x): itemgetter('data')(x) for x in err_data}, {itemgetter('id')(x): itemgetter('data')(x) for x in new_data}

    err_data.update(new_data)
    wateryessence
        4
    wateryessence  
       2021-08-13 14:42:49 +08:00
    result = new_data + [x for x in err_data if x['id'] not in {d['id'] for d in new_data}]
    strict
        5
    strict  
       2021-08-13 14:47:23 +08:00
    ChainMap(new_data, err_data)


    这样不是更 pythonnic 一点么.
    Macv1994
        6
    Macv1994  
    OP
       2021-08-13 14:54:16 +08:00
    @strict 我试试看 谢谢啊
    Macv1994
        7
    Macv1994  
    OP
       2021-08-13 14:54:29 +08:00
    YsHaNg
        8
    YsHaNg  
       2021-08-14 05:27:46 +08:00
    @Macv1994 err_dic = {item['id']:item['data'] for item in err_data}
    new_dic = {item['id']:item['data'] for item in new_data}
    result_dic = dict(zip(ChainMap(new_dic,err_dic).keys(),ChainMap(new_dic,err_dic).values()))
    Pzqqt
        9
    Pzqqt  
       2021-08-14 09:08:01 +08:00
    python 2 或 python 3.5 以下的版本:
    ```python
    result = dict(ChainMap(err_data, new_data))
    ```

    python 3.5 及以上版本:
    ```python
    result = {**err_data, **new_data}
    ```

    python 3.9 及以上版本:
    ```python
    result = err_data | new_data
    ```
    Pzqqt
        10
    Pzqqt  
       2021-08-14 09:10:37 +08:00
    等等,你这是列表啊,那先把 err_data 和 new_data 转为字典吧,`id`做键,`data`做值。
    lixiang2017
        11
    lixiang2017  
       2021-08-15 03:15:55 +08:00 via Android
    四楼是对的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1430 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 23:48 · PVG 07:48 · LAX 16:48 · JFK 19:48
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.