【问题标题】:Sort subdictionary lists by their dictionary's key values按字典的键值对子字典列表进行排序
【发布时间】:2018-07-19 11:27:34
【问题描述】:

我有一个 XML 文件(约 500 行),它在 Python 中被转换为嵌套的有序字典。我需要根据值对其进行排序,但是因为它嵌套太多并且里面有列表,所以我迷路了。我已经搜索了答案,试图找到一种对与列表混合的字典进行排序的方法。但到目前为止还没有运气。

这是我得到的最接近的。 Python: Sort nested dictionary by value 但是因为我有一个有 2 个子键“foo”和“bar”的键,它们有列表,里面有字典,这不是我需要的。

我想根据“日期”对“foo”和“bar”进行排序。或按“日期”值返回子字典。

我有一个循环遍历子词典的列表,但它不会对其进行排序。我试图改变它来修复它,但没有任何改变。这也无济于事,lambda 对我来说似乎很神奇。

for i in range(len(your_dict['History']['foo'])):
    mine = OrderedDict(sorted(your_dict.items(), key=lambda x: x[1]["foo"][i]['Date']))

手头词典的简短示例:

"History": {
    "@version": "4.0",
    "foo": [
        {"code": "ID", "Date": "2018-07-09T15:31:09+03:00"},
        {"Date": "2018-07-09T13:46:09+03:00"}
    ],
    "bar": [
        {"code": "ID", "Date": "2018-07-09T09:39:29+03:00"},
        {"code": "ID", "Date": "2018-07-09T09:48:25+03:00"}
    ]
}

那么“foo”和“bar”如何排序呢?

【问题讨论】:

    标签: python dictionary nested


    【解决方案1】:
    >>> s = dict((k,sorted(v, key=lambda x: x['Date'])) for k,v in d['History'].items() if type(v)==list)
    >>> s['foo']
    [{'Date': '2018-07-09T13:46:09+03:00'}, {'code': 'ID', 'Date': '2018-07-09T15:31:09+03:00'}]
    >>> s['bar']
    [{'code': 'ID', 'Date': '2018-07-09T09:39:29+03:00'}, {'code': 'ID', 'Date': '2018-07-09T09:48:25+03:00'}]
    

    说明 以下列表推导将 dict 项作为键值对返回

    [(k,v) for k,v in d['History'].items()]
    

    这将过滤键值对并仅在 value 类型为 list 时才包含它们

    [(k,v) for k,v in d['History'].items() if type(v)==list]
    # [('foo', [{'code': 'ID', 'Date': '2018-07-09T15:31:09+03:00'}, {'Date': '2018-07-09T13:46:09+03:00'}]), ('bar', [{'code': 'ID', 'Date': '2018-07-09T09:39:29+03:00'}, {'code': 'ID', 'Date': '2018-07-09T09:48:25+03:00'}])]
    

    我们现在要做的就是根据日期对每个值进行排序。 sorted(v, key=lambda x: x['Date'])) 会这样做

    将这些合并到一行中,就得到了上面提到的单行

    【讨论】:

    • 谢谢你,这一切都在一行中,正是我希望做的!你能解释一下它背后的逻辑吗?
    • 添加了一些解释
    • 非常感谢!现在我至少知道了,我在做什么:D
    【解决方案2】:

    sortedlambda 一起使用

    例如:

    d = {"History": {
        "@version": "4.0",
        "foo": [
            {"code": "ID", "Date": "2018-07-09T15:31:09+03:00"},
            {"Date": "2018-07-09T13:46:09+03:00"}
        ],
        "bar": [
            {"code": "ID", "Date": "2018-07-09T09:39:29+03:00"},
            {"code": "ID", "Date": "2018-07-09T09:48:25+03:00"}
        ]
        }
    }
    print(sorted(d["History"]["foo"], key=lambda k: k['Date']))
    print(sorted(d["History"]["bar"], key=lambda k: k['Date']))  
    

    输出:

    [{'Date': '2018-07-09T13:46:09+03:00'}, {'Date': '2018-07-09T15:31:09+03:00', 'code': 'ID'}]
    [{'Date': '2018-07-09T09:39:29+03:00', 'code': 'ID'}, {'Date': '2018-07-09T09:48:25+03:00', 'code': 'ID'}]
    

    【讨论】:

    • 可以将结果保存为变量吗?像 OrderedDict 一样?因为我以后需要它来汇总所有数据。
    • 您正在排序列表而不是字典...所以我认为您不需要OrderedDict
    【解决方案3】:

    问题是您正在尝试获取 .items,而您只想对列表进行排序,所以不需要所有这些东西,只需像这样简单明了:

    for i in ('foo', 'bar'):
       your_dict['History'][i] = sorted(your_dict['History][i], key=lambda x:x['date'])
    

    【讨论】:

    • 是的,否则它会引发 TypeError: tuple indices must be integers or slices, not strHistory 更改为 1 有效且不会引发错误。
    • @veteran007 顺便说一句,因为我没有足够的代表,我无法发表评论,但如果你有其他包含列表但不是正确数据的类别,sunitha 的答案将会失败。但是,如果您像这样保留它,那就没有问题了。
    • 是的,原来的xml文件是系统报告,所以我的dict的格式不会改变
    猜你喜欢
    • 1970-01-01
    • 2011-02-22
    • 2019-12-30
    • 2010-11-15
    • 2014-02-11
    • 1970-01-01
    • 2011-01-16
    • 1970-01-01
    相关资源
    最近更新 更多