python - 从两个字典创建一个新列表(不区分大小写)

标签 python dictionary

这是一个关于Python的问题。我有以下字典列表:

listA = [
          {"t": 1, "tid": 2, "gtm": "Goofy", "c1": 4, "id": "111"},
          {"t": 3, "tid": 4, "gtm": "goofy", "c1": 4, "c2": 5, "id": "222"},
          {"t": 1, "tid": 2, "gtm": "GooFy", "c1": 4, "c2": 5, "id": "333"},
          {"t": 5, "tid": 6, "gtm": "GoOfY", "c1": 4, "c2": 5, "id": "444"},
          {"t": 1, "tid": 2, "gtm": "GOOFY", "c1": 4, "c2": 5, "id": "555"}
        ]

还有一本我想比较的字典:

dictA = {"t": 1, "tid": 2, "gtm": "goofy"}

我想创建一个与 listAdictA 中的所有项目相匹配的字典列表,并包含“id”字段:

listB = [
          {"t": 1, "tid": 2, "gtm": "Goofy", "id": "111"},
          {"t": 1, "tid": 2, "gtm": "GooFy", "id": "333"},
          {"t": 1, "tid": 2, "gtm": "GOOFY", "id": "555"},
        ]

如何以不区分大小写的方式比较两个字典?

最佳答案

您必须手动测试每个字典值:

def test(d1, d2):
    """Test if all values for d1 match case-insensitively in d2"""
    def equal(v1, v2):
        try:
            return v1.lower() == v2.lower()
        except AttributeError:
            # not an object that supports .lower()
            return v1 == v2
    try:
        return all(equal(d1[k], d2[k]) for k in d1)
    except KeyError:
        # d2 is missing a key, not a match
        return False

listB = [d for d in listA if test(dictA, d)]

这会产生您正在寻找的 3 个匹配项:

>>> listA = [
...           {"t": 1, "tid": 2, "gtm": "Goofy", "c1": 4, "id": "111"},
...           {"t": 3, "tid": 4, "gtm": "goofy", "c1": 4, "c2": 5, "id": "222"},
...           {"t": 1, "tid": 2, "gtm": "GooFy", "c1": 4, "c2": 5, "id": "333"},
...           {"t": 5, "tid": 6, "gtm": "GoOfY", "c1": 4, "c2": 5, "id": "444"},
...           {"t": 1, "tid": 2, "gtm": "GOOFY", "c1": 4, "c2": 5, "id": "555"}
...         ]
>>> dictA = {"t": 1, "tid": 2, "gtm": "goofy"}
>>> [d for d in listA if test(dictA, d)]
[{'tid': 2, 'c1': 4, 'id': '111', 't': 1, 'gtm': 'Goofy'}, {'gtm': 'GooFy', 't': 1, 'tid': 2, 'c2': 5, 'c1': 4, 'id': '333'}, {'gtm': 'GOOFY', 't': 1, 'tid': 2, 'c2': 5, 'c1': 4, 'id': '555'}]
>>> from pprint import pprint
>>> pprint(_)
[{'c1': 4, 'gtm': 'Goofy', 'id': '111', 't': 1, 'tid': 2},
 {'c1': 4, 'c2': 5, 'gtm': 'GooFy', 'id': '333', 't': 1, 'tid': 2},
 {'c1': 4, 'c2': 5, 'gtm': 'GOOFY', 'id': '555', 't': 1, 'tid': 2}]

但这些包括额外的键。如果您必须只有某些键,请在新字典中选择这些键:

listB = [dict(dictA, id=d['id'], gtm=d['gtm']) for d in listA if test(dictA, d)]

这将创建 dictA 的副本,并添加匹配字典中的 idgtm 键:

>>> [dict(dictA, id=d['id'], gtm=d['gtm']) for d in listA if test(dictA, d)]
[{'tid': 2, 'id': '111', 't': 1, 'gtm': 'Goofy'}, {'tid': 2, 'id': '333', 't': 1, 'gtm': 'GooFy'}, {'tid': 2, 'id': '555', 't': 1, 'gtm': 'GOOFY'}]
>>> pprint(_)
[{'gtm': 'Goofy', 'id': '111', 't': 1, 'tid': 2},
 {'gtm': 'GooFy', 'id': '333', 't': 1, 'tid': 2},
 {'gtm': 'GOOFY', 'id': '555', 't': 1, 'tid': 2}]

关于python - 从两个字典创建一个新列表(不区分大小写),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39288989/

相关文章:

c# - 对象字典不适用于 JSON

python - 有效地就地过滤字典

python - 绘制同一社区或分区的网络和分组顶点

python - 寻找没有形状限制的 dataframe.apply()

python - 从数据帧中删除存储在变量中的系列

Python 的 `urllib2` : Why do I get error 403 when I `urlopen` a Wikipedia page?

python - 如何使用基于使用列的函数的条件选择 Python Dataframe 中的行

objective-c - 如何使用 route-me 创建透明层

python - 将字典中的字符串值转换为 int

python - 使用 Gensim 中的 filter_extremes 按频率过滤 token