首页 文章

列表理解中的奇怪解包[重复]

提问于
浏览
2

这个问题在这里已有答案:

我在看a lecture from David Beazley . 在23:20分钟,他做了一些"magic"解压,我很难理解 .

“魔术线”是

fail = [ { **row, 'DBA Name': row['DBA Name'].replace("'",'').upper() } for row in fail ]

我搜索了类似的例子,但我找不到任何 . 你能解释一下这段代码中发生了什么吗?你能指点我一些类似的例子吗?

2 回答

  • 2

    该片段在添加新元素时将字典文字中已存在的映射 row 解包 . 一个简化的例子证明了这一点:

    >>> r = {'a':1, 'b':2}    
    >>> {**r, 'Spam': 20}
    {'Spam': 20, 'a': 1, 'b': 2}
    

    这个解包只在Pythons> = 3.5中提供,与PEP 448一起引入;在以前的版本中它是 SyntaxError .

  • 1

    {**row} 只是解压缩字典(在python-3.5中的文字允许):

    >>> row = {'DBA Name': "make 'this' now", 'b': 2}
    >>> {**row}
    {'DBA Name': "make 'this' now", 'b': 2}
    

    基本上这只是制作 row 的副本,因为你将字典解压缩到字典中 .

    第二部分是普通的字典文字语法:

    >>> {'DBA Name': row['DBA Name'].replace("'",'').upper() }
    {'DBA Name': 'MAKE THIS NOW'}
    

    "magic"位是字典将唯一键映射到某个值,因此这实际上是 row 字典的副本,并用新值替换 'DBA Name' 键 . 这是有效的,因为文字从左到右解释:

    >>> { **row, 'DBA Name': row['DBA Name'].replace("'",'').upper() }
    {'DBA Name': 'MAKE THIS NOW', 'b': 2}
    

    通常,您只需创建字典的副本并替换密钥:

    >>> newrow = row.copy()
    >>> newrow['DBA Name'] = row['DBA Name'].replace("'",'').upper()
    

    但这在理解中是行不通的(在理解中的赋值是 SyntaxError )所以你需要一些"magic"(或调用特殊方法) .


    但你也可以通过嵌套理解来做到这一点(它更慢但可能不那么神奇):

    [        k: v.replace("'",'').upper() if key == 'DBA Name' else v 
     for row in fail 
         for k, v in row.items()]
    

    缩进可能看起来有点偏,但我发现以这种方式可视化更容易,你也可以只使用一行:

    [k: v.replace("'",'').upper() if key == 'DBA Name' else v for row in fail for k, v in row.items()]
    

相关问题