【问题标题】:conditionally replace python dictionary value with comprehension有条件地用理解替换python字典值
【发布时间】:2015-09-26 12:11:34
【问题描述】:

我正在通过 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'}

【问题讨论】:

  • 谢谢大家,{k:(v if v else None) for k,v in row.items()} 正是我想要的。我没有意识到我可以像这样嵌套 (v if v else None) 。欣赏它。

标签: python csv dictionary list-comprehension nonetype


【解决方案1】:

如果您使用的是 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

第二种方法很容易理解,也没有创建额外的列表,这对更高的性能更好

【讨论】:

    【解决方案2】:

    您的问题是您正在更改名称 row 以在 for 循环中引用新字典,这不会更改原始列表/DictReader 对象 - data 中的任何内容。

    如果 data 是一个列表,您应该枚举 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()})
    

    【讨论】:

    • newdata = [{k:(v if v else None) for k,v in row.items()} for row in data] ?
    • 是的,也可以。
    【解决方案3】:

    您的主要错误是您尝试对字典进行两次迭代,而您只需要执行一次。

    试试:

    data = {k:(v if v else None) for k,v in data.items()}
    

    没有for循环。

    【讨论】:

    • 数据是类列表,不是字典,行是字典。
    • 你说得对,应该更仔细地阅读问题。
    猜你喜欢
    • 1970-01-01
    • 2022-11-23
    • 1970-01-01
    • 1970-01-01
    • 2014-06-18
    • 1970-01-01
    • 2013-11-15
    • 1970-01-01
    • 2014-08-23
    相关资源
    最近更新 更多