我正在通过csv.DictReader
在csv中阅读,并尝试将所有空值替换为None
值。 DictReader
似乎将文件作为字典的实例,其中CSV的每一行都是字典(我很好)。但是当我尝试按行/词典遍历行/词典并用""
替换任何空值(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'}
答案 0 :(得分:3)
您的问题是您正在更改名称row
以引用for循环中的新字典,这不会更改原始列表/ 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类,因此无法直接更改DictReader对象,因此您应该创建一个新列表,并在新列表中添加更改的行(或者DictWriter对象,更喜欢DictWriter对象) -
示例 -
>>> newdata = []
>>> for row in data:
... newdata.append({k:(v if v else None) for k,v in row.items()})
答案 1 :(得分:0)
您的主要错误是您尝试在字典上迭代两次,而您只需要执行一次。
尝试:
data = {k:(v if v else None) for k,v in data.items()}
没有for-loop。
答案 2 :(得分:0)
如果您使用的是CSV并且数据太大,请使用iteritems()
这将节省防止由items()引起的大型列表生成 尝试:
new_data=[]
for row in data:
new_data.append({k:(v if v else None) for k,v in row.iteritems()})
如果你不理解理解,请遵循这个简单的for循环:
for row in data:
for k,v in row.iteritems():
if not v:
row[k]=None
第二种方法很容易理解,也没有创建额外的列表,这对于更高的性能更好