有条件地用理解替换 python 字典值
conditionally replace python dictionary value with comprehension
我正在通过 csv.DictReader
读取 csv 并尝试用 None
值替换任何空值。 DictReader
似乎将文件作为字典的一个实例,其中 CSV 的每一行都是一个字典(我很好)。但是,当我尝试通过 row/dictionary 遍历它 row/dictionary 并将任何空值 (""
) 替换为 None
时,我似乎没有被卡住。我以前把它写成这样的列表理解:
for row in data:
row = [None if not x else x for x in row]
但我需要改用字典而不是列表。我以前没有任何字典理解的经验,但是当我尝试将它扩展到字典时,我就是无法让它工作。我在想一些事情:
for row in data:
row.values() = [None if not x else x for x in row.values()}
但我刚得到 SyntaxError: invalid syntax.
。我已经尝试了很多其他的东西(太多了,不能在这里列出),比如:
for row in data:
row = {k:None for k,v in row if v not v else v}
但这好像也有同样的问题
作为参考,我的数据如下:
{'colour': 'ab6612', 'line': '1', 'name': 'Baker', 'stripe': ''}
{'colour': 'f7dc00', 'line': '3', 'name': '', 'stripe': 'FFFFFF'}
理想情况下最终会是:
{'colour': 'ab6612', 'line': '1', 'name': 'Baker', 'stripe': None}
{'colour': 'f7dc00', 'line': '3', 'name': None, 'stripe': 'FFFFFF'}
您的主要错误是您试图在字典上迭代两次,而您只需要执行一次。
尝试:
data = {k:(v if v else None) for k,v in data.items()}
没有 for 循环。
如果您使用的是 CSV 并且数据太大,请使用 iteritems()
this will save prevent the large list generation caused by items()
Try:
new_data=[]
for row in data:
new_data.append({k:(v if v else None) for k,v in row.iteritems()})
if you dont understand comprehensions follow this simple for loop:
for row in data:
for k,v in row.iteritems():
if not v:
row[k]=None
the second method is easy to understand also does not create an additional list which is a better for higher performance
您的问题是您正在更改名称 row
以在 for 循环中引用新字典,这不会更改原始 list/DictReader 对象 - data
中的任何内容。
如果数据是一个列表,您应该枚举 data
并更改数据中的字典(或使该引用成为新字典)
例子-
for i,row in enumerate(data):
data[i] = {k:(v if v else None) for k,v in row.items()}
示例测试-
>>> data = [{1:2 , 3:''},{4:'',5:6}]
>>> for i,row in enumerate(data):
... data[i] = {k:(v if v else None) for k,v in row.items()}
...
>>> data
[{1: 2, 3: None}, {4: None, 5: 6}]
并且由于您使用的是 DictReader class,您不能直接更改 DictReader 对象,因此您应该创建一个新列表,并将更改的行添加到新列表(或 DictWriter 对象,将更喜欢 DictWriter 对象)-
例子-
>>> newdata = []
>>> for row in data:
... newdata.append({k:(v if v else None) for k,v in row.items()})
我正在通过 csv.DictReader
读取 csv 并尝试用 None
值替换任何空值。 DictReader
似乎将文件作为字典的一个实例,其中 CSV 的每一行都是一个字典(我很好)。但是,当我尝试通过 row/dictionary 遍历它 row/dictionary 并将任何空值 (""
) 替换为 None
时,我似乎没有被卡住。我以前把它写成这样的列表理解:
for row in data:
row = [None if not x else x for x in row]
但我需要改用字典而不是列表。我以前没有任何字典理解的经验,但是当我尝试将它扩展到字典时,我就是无法让它工作。我在想一些事情:
for row in data:
row.values() = [None if not x else x for x in row.values()}
但我刚得到 SyntaxError: invalid syntax.
。我已经尝试了很多其他的东西(太多了,不能在这里列出),比如:
for row in data:
row = {k:None for k,v in row if v not v else v}
但这好像也有同样的问题
作为参考,我的数据如下:
{'colour': 'ab6612', 'line': '1', 'name': 'Baker', 'stripe': ''}
{'colour': 'f7dc00', 'line': '3', 'name': '', 'stripe': 'FFFFFF'}
理想情况下最终会是:
{'colour': 'ab6612', 'line': '1', 'name': 'Baker', 'stripe': None}
{'colour': 'f7dc00', 'line': '3', 'name': None, 'stripe': 'FFFFFF'}
您的主要错误是您试图在字典上迭代两次,而您只需要执行一次。
尝试:
data = {k:(v if v else None) for k,v in data.items()}
没有 for 循环。
如果您使用的是 CSV 并且数据太大,请使用 iteritems()
this will save prevent the large list generation caused by items() Try:
new_data=[]
for row in data:
new_data.append({k:(v if v else None) for k,v in row.iteritems()})
if you dont understand comprehensions follow this simple for loop:
for row in data:
for k,v in row.iteritems():
if not v:
row[k]=None
the second method is easy to understand also does not create an additional list which is a better for higher performance
您的问题是您正在更改名称 row
以在 for 循环中引用新字典,这不会更改原始 list/DictReader 对象 - data
中的任何内容。
如果数据是一个列表,您应该枚举 data
并更改数据中的字典(或使该引用成为新字典)
例子-
for i,row in enumerate(data):
data[i] = {k:(v if v else None) for k,v in row.items()}
示例测试-
>>> data = [{1:2 , 3:''},{4:'',5:6}]
>>> for i,row in enumerate(data):
... data[i] = {k:(v if v else None) for k,v in row.items()}
...
>>> data
[{1: 2, 3: None}, {4: None, 5: 6}]
并且由于您使用的是 DictReader class,您不能直接更改 DictReader 对象,因此您应该创建一个新列表,并将更改的行添加到新列表(或 DictWriter 对象,将更喜欢 DictWriter 对象)-
例子-
>>> newdata = []
>>> for row in data:
... newdata.append({k:(v if v else None) for k,v in row.items()})