在Python中,如果值是nan/null/empty,如何从字典的列表中删除key和value?

4 人不认可

在Python中,如果值是nan/null/empty,如何从字典的列表中删除key和value。我试着用下面的代码来删除,但它没有被删除。 在代码中是否有什么错误的做法。

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

Code tried

1st method tried

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

2nd method tried

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

地址_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}]}

Expected Output

{'source_id': 4402350, 'address': [{'address_type': 'Primary', 'address_line_1': '11815'}, {'address_type': 'work', 'address_line_2': 123}]}
    
2 个评论
循环使用字典时,突变字典是行不通的。你必须创建一个新的,并且只用你想要的数据来填充它。
同意 @yedpodtrzitk 的意见,你不能在迭代字典的时候改变它。唯一的办法是创建一个新的 dictionary。
python
json
dictionary
Naveen
Naveen
发布于 2021-09-03
4 个回答
Ashyam
Ashyam
发布于 2021-09-03
已采纳
0 人赞同

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

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

Output

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

One-Liner

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 "值是浮点类型,你有多种选择来检查nan。1) Pandas: pd.isna() 2) Numpy: 【替换代码1
key:val在这里起什么作用?
它是一个字典的理解。基本上是创建一个字典,同时循环浏览一组键值对。所以如果你把这一行拆开,首先我用 for key, val in addr.items() 循环查看 address 列表中每个项目的键值,然后我用 if val == val 检查 val 是否是一个 nan。如果条件得到满足,那么我就用 key: val 在新的字典中创建键值对。注意这一行是用大括号括起来的,意味着你正在创建一个字典。你可以查一下列表/字典的理解,以便更好地理解这个语法。
balderman
balderman
发布于 2021-09-03
0 人赞同

Like the below

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)

output

{'source_id': 4402350, 'address': [{'address_type': 'Primary', 'address_line_1': '11815'}, {'address_type': 'work', 'address_line_2': 123}]}
    
No, he's not checking the key, he's checking entry[key] , which is correct.
@Naveen 你复制/粘贴了我的代码并运行它吗?据我所知,它所做的正是你所要求的。你为什么不接受这个答案呢?
它对我不起作用。如果你的答案能解决这个问题,我没有任何问题。
你复制/粘贴并运行它了吗?输出的结果是什么?
是的,我已经复制/粘贴了代码并运行它。我得到的输出与输入相同。
Naveen
Naveen
发布于 2021-09-03
0 人赞同
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
    
你能补充关于建议的代码如何解决这个问题的细节吗?只有代码的回答是没有什么帮助的,对被问者和其他人都是如此。
deblue
deblue
发布于 2021-09-03
0 人赞同

在这个问题上有两个问题。首先,你有这样的问题:你的 values 中的一些 dict 是字典的列表。其次,你不能在循环过程中改变字典,所以你需要进行复制。

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)