如何在一行for循环中的字典中添加另一个属性[重复]

Posted

技术标签:

【中文标题】如何在一行for循环中的字典中添加另一个属性[重复]【英文标题】:How to add another attribute in dictionary inside a one line for loop [duplicate] 【发布时间】:2020-10-27 10:52:42 【问题描述】:

我有一个字典列表和一个字符串。我想在列表内的每个字典中添加一个 selected 属性。我想知道这是否可以使用一个衬垫。

这是我的输入:

saved_fields = "apple|cherry|banana".split('|')
fields = [
    
        'name' : 'cherry'
    , 
    
        'name' : 'apple'
    , 
    
        'name' : 'orange'
    
]

这是我的预期输出:

[
    
        'name' : 'cherry',
        'selected' : True
    , 
    
        'name' : 'apple',
        'selected' : True
    , 
    
        'name' : 'orange',
        'selected' : False
    
]

我试过这个:

new_fields = [item [item['selected'] if item['name'] in saved_fields] for item in fields]

【问题讨论】:

您确定您的代码复制正确吗?看起来这将是一个错误。 “我试过这个”——结果如何?你得到了什么错误或输出?你是如何尝试修复它的?有些人(部分包括我自己)喜欢仅仅为了它而看到尝试,但真正的重点应该是对其进行迭代并将其分解并调试它,也许这会导致你提出一个不同的问题,或者它只是引导您找到答案。 你能多行吗?从那里开始然后将其转换为单行可能比尝试直接提出单行要容易得多。虽然“单行”问题是什么?试图将某些内容强行放在一行中只会导致无法阅读的代码。 A "one line for-loop" 在您的情况下是 dict 理解。 (或列表理解,或集合理解)。请阅读dict理解 【参考方案1】:
['name': item['name'], 'selected': item['name'] in saved_fields for item in fields]

【讨论】:

【参考方案2】:
result = [
    "name": fruit['name'],
     "selected": fruit['name'] in saved_fields  
    for fruit in fields
]

>>> ['name': 'cherry', 'selected': True,
 'name': 'apple', 'selected': True,
 'name': 'orange', 'selected': False]

作为一个单行:

result = ["name": fruit['name'], "selected": fruit['name'] in saved_fields for fruit in fields]

【讨论】:

【参考方案3】:

我不一定认为“单线方式”是最好的方式。

s = set(saved_fields)  # set lookup is more efficient 
for d in fields:
    d['status'] = d['name'] in s

fields
# ['name': 'cherry', 'status': True,
#  'name': 'apple', 'status': True,
#  'name': 'orange', 'status': False]

简单。明确的。很明显。

这会就地更新您的字典,如果您有很多记录或其他键(除了“名称”和“状态”之外没有告诉我们的情况)会更好。


如果你坚持单线,这是一个保留其他键:

[**d, 'status': d['name'] in s for d in fields]  
# ['name': 'cherry', 'status': True,
#  'name': 'apple', 'status': True,
#  'name': 'orange', 'status': False]

这是list comprehension syntax,它会创建一个新的字典列表,保持原样不变。

**d, ... 部分对于保留未被修改的密钥是必需的。我没有看到任何其他答案,所以认为值得一提。

扩展解包语法仅适用于python3.5+,对于旧版本,将**d, 'status': d['name'] in s更改为dict(d, **'status': d['name'] in s)

【讨论】:

你应该向 OP 解释这个 "one line for-loop" 是一个dict理解 @smci 但这不是听写理解吗?这是一个列表理解,每次迭代都会创建一个字典。虽然我的回答的重点是你并不总是需要使用一个。 @smci 不,dict 理解看起来像key : value for something in something_else**d, 'a': 'b', 'c': 'd' 只是创建一个字典。 cs95:不,我没有投反对票!没那么偏执,我的朋友。我不相信我曾经否决过您在 SO 上的任何优秀内容,也许只有一个答案一次。当然不是这个。 “第二个答案只是满足OP的“一条线”要求的鲱鱼,就像我说的不是答案的重点”。我其实更喜欢它!我很喜欢。此外,来自函数式语言的人也会喜欢它。【参考方案4】:

您可以使用所选密钥更新dictionary

for x in fields: x.update('selected': x['name'] in saved_fields):

print(fields)

['name': 'cherry', 'selected': True, 
'name': 'apple', 'selected': True, 
'name': 'orange', 'selected': False]

【讨论】:

我强烈不建议对副作用使用列表推导,这是well-known antipattern。您正在生成 [None, None, None] 的结果并将其丢弃。 好点,根据 OP 的要求更新为不同的班轮。【参考方案5】:

即使字典中有多个条目,建议的解决方案也可以工作。

接受您的意见:

saved_fields = "apple|cherry|banana".split('|')
fields = [
    
        'name' : 'cherry'
    , 
    
        'name' : 'apple'
    , 
    
        'name' : 'orange'
    
]

    使用Dict.update()

    >>> [item.update('selected': item['name'] in saved_fields) for item in fields]
    [None, None, None]
    

    将返回 [None, None, None],但会在原地修改 fields 变量。

    >>> fields
    ['name': 'cherry', 'selected': True,
     'name': 'apple', 'selected': True,
     'name': 'orange', 'selected': False]
    

    请注意,虽然这是单行,但这是 not always recommended.

    如果您想要一个不修改 fields 的新列表。可以在 Dict cf 上使用 ** 运算符来完成,如@cs95 答案所示。 ** explanation:

    >>> new_fields = [**item, 'selected': item['name'] in saved_fields for item in fields]
    >>> new_fields
    ['name': 'cherry', 'selected': True,
     'name': 'apple', 'selected': True,
     'name': 'orange', 'selected': False]
    
    >>> fields
    ['name': 'cherry', 'name': 'apple', 'name': 'orange']
    

【讨论】:

将列表推导用于副作用是 Python anti-pattern

以上是关于如何在一行for循环中的字典中添加另一个属性[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何在 django 模板中从 for 循环中转义一行

For循环正在覆盖列表中的字典值[重复]

使用for循环添加一个字符串数组和另一个字符串[重复]

如何通过带有for循环的字典(python)设置实例的属性

从python中的for循环返回值

python 如何循环读取字典中的keys所对应的values