使用Python列表推导式更新字典值

22
我有一个字典列表,希望在键值为'price'且其值为空时将其更新为0。
data=[a['price']=0 for a in data if a['price']=='']

有没有可能做到这样的事情?我也尝试过

a.update({'price':0})

但是效果不太好...


你不能使用data=[a['price']=0 for a in data if a['price']==''],这是用于识别列表而不是更改它。 - Zeinab Abbasimazar
6个回答

36

赋值语句是语句,而语句不能在列表推导式中使用。只需使用普通的for循环:

data = ...
for a in data:
    if a['price'] == '':
        a['price'] = 0

为了完整起见,你也可以使用这个可怕的东西(但这并不意味着你应该这样做):

data = ...

[a.__setitem__('price', 0 if a['price'] == '' else a['price']) for a in data]

4
不,你确实不应该使用列表推导式。你正在构建一个None引用的列表,然后立即丢弃该列表。这是浪费计算资源和内存。只有在创建列表对象时才应使用列表推导式,而不是普遍替代for循环。 - Martijn Pieters
2
随意编辑答案的那部分,但我真的不认为我暗示这是一个好主意。如果需要,可以这样做。 - Markus Unterwaditzer

11
如果你正在使用 dict.update,请不要将其赋值给原始变量,因为它会返回 None。
[a.update(price=0) for a in data if a['price']=='']

没有进行分配的情况下将更新列表...


1

虽然不是很好的做法,但这是可行的:

import operator

l = [
    {'price': '', 'name': 'Banana'},
    {'price': 0.59, 'name': 'Apple'},
    {'name': 'Cookie', 'status': 'unavailable'}
]

[operator.setitem(p, "price", 0) for p in l if "price" in p and not p["price"]]

如果p["price"]的值为False、空字符串或其他Python认为为False的值,那么将处理不存在"price"键的情况,并将价格设置为0

请注意,列表推导式会返回垃圾值,如[None]


2
你已经注意到了,但是你真的不应该使用列表推导式。你正在构建一个None引用列表,然后立即丢弃该列表。这是浪费循环和内存的行为。列表推导式只应在创建列表对象时使用,而不是作为一般for循环的替代品。 - Martijn Pieters
很有趣。我一直觉得使用列表推导式而不是for..循环是“义务”的,因为我认为它们更有效率。我想我把它和生成器混淆了。 - Mathieu Dhondt

1

字典推导式

data = [
    {'price': '', 'id': 0},
    {'price': 7, 'id': 1},
    {'price': 26, 'id': 2},
]
data = [{k: 0 for k in d if k == 'price'} if d['price'] == '' else d for d in data]
print(data)

[
    {'price': 0, 'id': 0},
    {'price': 7, 'id': 1},
    {'price': 26, 'id': 2},
]

1

是的,你可以。

直接使用 update 更新字典是行不通的,因为 update 没有返回值,而且字典只是此处(在列表推导式内)的临时变量,所以没有影响。但是,你可以将其应用于可迭代对象本身,因为可迭代对象在这种情况下是持久的变量。

可以尝试使用

[my_dict['k'] = 'v' for my_dict in iterable]  # As I know, assignment not allowed in list comprehension

使用

[iterable[i].update({'k': 'v'}) for i in range(len(iterable))]  # You can use enumerate also

所以列表推导本身将返回无用数据,但您的字典将被更新。

0
不要使用返回None的update方法,而是将字典与另一个字典合并,其中存储了价格键的默认值。
>>> data = [{"price": 1}, {"price": ""}]
>>> default_price = {"price": 0}
>>> [d if d["price"] else {**d, **default_price} for d in data]
[{'price': 1}, {'price': 0}]

这将适用于 Python 3.5 或更高版本。从 Python 3.9 开始,您还可以使用并集运算符。

>>> [d if d["price"] else d | default_price for d in data]
[{'price': 1}, {'price': 0}]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接