python复杂结构去重

举例:

a = [
  {'key_name': 'name', 'key_type': 'varchar', 'value': '张三'},
  {'key_name': 'sex', 'key_type': 'int', 'value': '1'},
  {'key_name': 'address', 'key_type': 'varchar', 'value': '江苏省南京市'}
]

b = [
  {'key_name': 'name', 'key_type': 'varchar', 'value': '张三'},
  {'key_name': 'sex', 'key_type': 'int', 'value': '2'},
  {'key_name': 'address', 'key_type': 'varchar', 'value': '山东省济南市'}
]

a为原始数据,b为更新数据,可以看到b相对于a中,key_name='name'的该字典没有发生任何改变,然而剩余两个字典的部分内容被修改,假设ab两个列表长度较大,我如何快速取出需要更新的是key_name='sex'和key_name='address'的这两个字典?

ps:字典中的key所属的value均可变、如果ab两个数据集比较长,怎么样更科学呢

阅读 2.2k
4 个回答

这里面涉及的细节很多
1.元素个数是否一样
2.顺序是否一样
3.是否不存在缺失项
4.是仅value不同,还是说type可能也不同
如果以上都是一致的,那遍历索引值,比较字典元素的value就可以了
如果不是则都需要预处理

第一种,把字典列表转成以key_name值为key,每个字典为value的字典,然后直接用字典逐个比较
第二种,把字典列表转成DataFrame,直接比较

这些数据处理可以考虑pandas库,pip install pandas

import pandas as pd
a = [
  {'key_name': 'name', 'key_type': 'varchar', 'value': '张三'},
  {'key_name': 'sex', 'key_type': 'int', 'value': '1'},
  {'key_name': 'address', 'key_type': 'varchar', 'value': '江苏省南京市'}
]
df = pd.DataFrame(a)
dd = df[df['key_name']=='address'].value  # 综括号里是数据筛选的条件df['key_name']=='address'
df['value'][dd.index]= 'xxx' # 此处赋值的值xxx你可以将b也转为df的DataFrame格式,通过条件筛选拿到value值,即为此处的xxx
res = df.to_dict('records')

使用pandas的compare函数可以比较:

# -*- coding: utf-8 -*-

import pandas as pd


def main():
    a = [
        {"key_name": "name", "key_type": "varchar", "value": "张三"},
        {"key_name": "sex", "key_type": "int", "value": "1"},
        {"key_name": "address", "key_type": "varchar", "value": "江苏省南京市"},
    ]

    b = [
        {"key_name": "name", "key_type": "varchar", "value": "张三"},
        {"key_name": "sex", "key_type": "int", "value": "2"},
        {"key_name": "address", "key_type": "varchar", "value": "山东省济南市"},
    ]

    da = pd.DataFrame.from_dict(a)
    db = pd.DataFrame.from_dict(b)

    ret = da.compare(db, keep_shape=True, keep_equal=True)
    # print(ret["value"])

    for index, row in ret.iterrows():
        val = row["value"]
        if val["self"] != val["other"]:
            print("发生变化的行:")
            print(
                "a: key_name[%s] key_type[%s] value[%s]"
                % (row["key_name"]["self"], row["key_type"]["self"], val["self"])
            )
            print(
                "b: key_name[%s] key_type[%s] value[%s]"
                % (row["key_name"]["other"], row["key_type"]["other"], val["other"])
            )


if __name__ == "__main__":
    main()

最后输出a和b中不同的行:

$ python test.py
发生变化的行:
a: key_name[sex] key_type[int] value[1]
b: key_name[sex] key_type[int] value[2]
发生变化的行:
a: key_name[address] key_type[varchar] value[江苏省南京市]
b: key_name[address] key_type[varchar] value[山东省济南市]
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题