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

请教一个 dict 中取相同 value 的方法

  •  
  •   plko345 · 2021-03-13 16:52:13 +08:00 · 1975 次点击
    这是一个创建于 1358 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现在有一个 list, 每个元素都是一个 dict, 像下面这样

    [
        {
            "labels": {
                "k_1": "v_1",
                "k_2": "v_2",
                "k_3": "v_3_1"
            }
        },
        {
            "labels": {
                "k_1": "v_1",
                "k_2": "v_2",
                "k_3": "v_3_2"
            }
        },
        ......
    ]
    

    现在想要把其中 k_1 和 k_2 的 value 相同的, 但 k_3 的 value 不同的, 拿出来, 变成下面这样

    [
        {
            "labels": {
                "k_1": "v_1",
                "k_2": "v_2"
            },
            "targets": ["v_3_1", "v_3_2"]
        },
        ......
    ]
    

    有什么快速的算法吗?

    9 条回复    2021-03-16 17:23:59 +08:00
    imn1
        1
    imn1  
       2021-03-13 17:01:14 +08:00
    应该好多人不知道这种写法
    d1.items() & d2.items()
    d1.items() - d2.items()
    d2.items() - d1.items()

    keys()也可以这样写,但 values()不行
    no1xsyzy
        2
    no1xsyzy  
       2021-03-14 21:34:00 +08:00   ❤️ 1
    用 (d['labels']['k_1'], d['labels']['k_2']) 为 key 重建一个新的 dict,然后再构造成新的
    这个似乎是 O(n + m),其中 n 是原列表的长度,m 是新列表的长度。特别地,当 m 比较小的时候复杂度是 O(nm),随着 m 增大到某一数值就会变成 O(n + m),此时中间形态的 dict 的实现方式(自动地)从 k-v array 转为 hash map 。
    plko345
        3
    plko345  
    OP
       2021-03-15 10:44:58 +08:00 via Android
    @no1xsyzy 感谢,我试试
    HelloViper
        4
    HelloViper  
       2021-03-15 15:54:09 +08:00
    temp = {}
    for x in data:
    temp[(x['labels']['k_1'], x['labels']['k_2'])] = [*temp.get((x['labels']['k_1'], x['labels']['k_2']),[]), x['labels']['k_3']]
    plko345
        5
    plko345  
    OP
       2021-03-15 22:45:37 +08:00
    @HelloViper 可是每个 dict 中的 k_1 和 k_2 的 value 并不总是相同的
    plko345
        6
    plko345  
    OP
       2021-03-15 22:46:54 +08:00
    @HelloViper 抱歉, 我没写清楚, labels 中存在 n 个元素, 即 k_n
    HelloViper
        7
    HelloViper  
       2021-03-16 10:36:29 +08:00   ❤️ 1
    @plko345 你干脆转 pandas 随便玩吧,想怎么 groupby 都行,吧要聚合的列 apply list
    zyb201314
        8
    zyb201314  
       2021-03-16 14:10:54 +08:00 via Android
    #竟然没人用一楼方案?
    data = [
    {
    "labels": {
    "k_1": "v_1",
    "k_2": "v_2",
    "k_3": "v_3_1"
    }
    },
    {
    "labels": {
    "k_1": "v_1",
    "k_2": "v_2",
    "k_3": "v_3_2"
    }
    }
    ]
    ################################
    label_name = next((next((j for j in i)) for i in data))
    labels = data[0][label_name]
    #获取第一个 labels 的字典.
    targets = {}
    ################################
    for d in data:
    for j in d:
    labels = dict(labels.items() & d[j].items())
    targets = dict(targets.items() ^ d[j].items())
    ################################
    data=[{str(label_name): labels},{'targets': targets}]
    print(data)
    HelloViper
        9
    HelloViper  
       2021-03-16 17:23:59 +08:00
    @zyb201314 还可以|,经典的 sum dict:
    def _sum_dict(a, b):
    temp = dict()
    for key in a.keys() | b.keys():
    temp[key] = sum([d.get(key, 0) for d in (a, b)])
    return temp
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2579 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 05:30 · PVG 13:30 · LAX 21:30 · JFK 00:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.