【问题标题】:How to remove key and value both from list of dictionary if value is nan/null/empty in python如果python中的值为nan/null/empty,如何从字典列表中删除键和值
【发布时间】:2021-09-03 07:12:35
【问题描述】:

如果值在 python 中为 nan/null/empty,如何从字典列表中删除键和值。我试图使用下面的代码删除,但它没有被删除。 代码有什么问题吗。

如果 value 是 nan/null/empty,我们需要键值对。

代码尝试

尝试了第一种方法

for key,value in address_dic.items():
    if value is 'nan':
        del address_dic[key]
        

尝试了第二种方法

for key,value in dict(address_dic[address]).items():
    if value is 'nan':
        del address_dic[address][key]
        

在address_dic中输入数据

{'source_id': 4402350, 'address': [{'address_type': 'Primary', 'address_line_1': '11815', 'address_line_2': nan}, {'address_type': 'work', 'address_line_1': nan, 'address_line_2': 123}]}

预期输出

{'source_id': 4402350, 'address': [{'address_type': 'Primary', 'address_line_1': '11815'}, {'address_type': 'work', 'address_line_2': 123}]}

【问题讨论】:

  • 在循环遍历字典时改变字典不起作用。你必须创建一个新的并只用你想要的数据填充它。
  • 同意@yedpodtrzitk,迭代时不能更改字典。唯一的方法是创建一个新字典。

标签: python json dictionary


【解决方案1】:

在迭代字典或列表的值时,您不应修改它。创建一个新的地址列表,其中包含您需要的值并用它替换现有列表。

输入数据

address_dic = {
    "source_id": 4402350,
    "address": [
        {
            "address_type": "Primary",
            "address_line_1": "11815",
            "address_line_2": float("nan")
        },
        {
            "address_type": "work",
            "address_line_1": float("nan"),
            "address_line_2": 123
        }
    ]
}

主逻辑

new_address = []

for addr in address_dic["address"]:
    # iterate through the dictionary and add the key-value pair
    # into a new dictionary if the value is not nan
    new_addr = {key: val for key, val in addr.items() if val == val} 
    new_address.append(new_addr)

address_dic["address"] = new_address

输出

{
    "source_id": 4402350,
    "address": [
        {
            "address_type": "Primary",
            "address_line_1": "11815",
        },
        {
            "address_type": "work",
            "address_line_2": 123
        }
    ]
}

单线

address_dic["address"] = [{key: val for key, val in addr.items() if val == val} for addr in address_dic["address"]]

您可以通过多种方式检查值是否为 nan:

val = float("nan") # setting val as nan

熊猫

import pandas as pd
pd.isna(val) # returns True if val is nan

Numpy

import numpy as np
np.isnan(val) # returns True if val is nan

没有外部库

val == val # returns False if val is nan

【讨论】:

  • 它没有在最终输出中删除“nan”
  • 我怀疑它正在转换为其他值而不是 'nan'
  • 如果您的案例中的 'nan' 值是 float 类型,您可以使用多个选项检查 nan:1) Pandas:pd.isna() 2) Numpy:np.isnan()
  • key:val 在这里起什么作用?
  • 它是一个字典理解。基本上在遍历一组键值对时创建字典。因此,如果您打破该行,首先我使用for key, val in addr.items() 循环遍历address 列表中每个项目的键值,然后使用if val == val 检查val 是否不是nan。如果满足条件,那么我将使用key: val 在新字典中创建键值对。请注意,该行用花括号括起来,这意味着您正在创建字典。您可以查看列表/字典理解以更好地理解语法。
【解决方案2】:

喜欢下面的

data = {'source_id': 4402350,
        'address': [{'address_type': 'Primary', 'address_line_1': '11815', 'address_line_2': 'nan'},
                    {'address_type': 'work', 'address_line_1': 'nan', 'address_line_2': 123}]}

for entry in data['address']:
    for k in list(entry.keys()):
        if entry[k] == 'nan':
            del entry[k]
print(data)

输出

{'source_id': 4402350, 'address': [{'address_type': 'Primary', 'address_line_1': '11815'}, {'address_type': 'work', 'address_line_2': 123}]}

【讨论】:

  • 不,他不是在检查密钥,而是在检查entry[key],这是正确的。
  • @Naveen 你复制/粘贴我的代码并运行它了吗?据我所知,它完全符合您的要求。为什么不接受答案?
  • 它对我没有用。如果可以解决问题,我没有任何问题可以接受您的回答。
  • 您是否复制/粘贴并运行它?输出是什么?
  • 是的,我有复制/粘贴代码并运行它。我得到的输出与输入相同。
【解决方案3】:
for addr in address_dic[address]:
    new_addr = {key: val for key, val in addr.items() if val == val}
    new_address.append(new_addr)
print(new_address)
address_dic["address"] = new_address

【讨论】:

  • 您能否添加有关建议代码如何解决问题的详细信息?仅代码的答案不是很有帮助,对被问者和其他人都没有。
【解决方案4】:

这个问题有两个问题。首先,您的dict 中有一些values 是字典列表的问题。其次,您不能在循环时更改字典,因此您需要制作副本。

试试:


d = {'source_id': 4402350, 'address': [{'address_type': 'Primary', 'address_line_1': '11815', 'address_line_2': 'nan'}, {'address_type': 'work', 'address_line_1': 'nan', 'address_line_2': 123}]}



for k,v in d.copy().items():
    if type(v) == list:
        for i, dd in enumerate(v):
            for k1,v1 in dd.copy().items():
                if v1 == 'nan':
                    dd.pop(k1)
                    v[i] = dd
    else:
        if v == 'nan':
            d.pop(k)

print(d)


【讨论】:

  • 我们无法更改输入。我可以在您放入 np.nan 的输入数据中看到。
  • 已更改,我不清楚它是 np.nan 还是 'nan',因为您缺少第一个 nan 条目上的报价。
  • 我已将输入数据按打印后得到的原样放置 address_dic["address"
  • 您确定第一个条目只是 nan 而第二个条目是 'nan'?
  • 我们的值是 nan.. 我不知道第一个条目还是第二个条目
猜你喜欢
  • 2018-05-01
  • 2020-09-23
  • 2022-01-06
  • 2017-07-04
  • 2020-03-11
  • 1970-01-01
  • 1970-01-01
  • 2018-09-23
  • 2017-06-21
相关资源
最近更新 更多