I have a list of dicts. For each dict, I need to pass one of its properties to a function, and then assign a new property based on the result of that function.
For example: I have a list of pages of a site. I need to loop through them and, based on the URL, assign the author name to a property in the dict.
for index, page in enumerate(pages):
pages[index]['author'] = get_author(page['url'])
This works. But's cluttered and doesn't feel pythonic. pages[index]
feels like a thing that I shouldn't have to do in Python.
Is there a way to do this via a list comprehension? Or some other more pythonic way?
pages = [??? for page in pages]
You could use such a list
comprehension:
result = [{**page, 'author': get_author(page['url'])}
for page in pages]
# This works too:
result = [dict(**page, author=get_author(page['url']))
for page in pages]
# but is less preferred because it will fail for input containing non-string keys
This creates a new dict
for each original dict
with an extra key, author
, based on the value of get_author
as applied to the value corresponding to the url
key.
Note that it does not modify the original list
.
Example:
def get_author(i):
if i == 1:
return 'hello'
else:
return 'bye'
pages = [{'url': 1},
{'url': 2}]
result = [{**page, **{'author': get_author(page['url'])}} for page in pages]
print(result)
Output:
[{'url': 1, 'author': 'hello'}, {'url': 2, 'author': 'bye'}]
A list comprehension builds a list from an existing list. In your case, you want to update existing list items. A list comprehension is inappropriate for this job.
Your solution can be somewhat improved, though:
for page in pages:
page['author'] = get_author(page['url'])
I can see two "pythonic" solutions:
pages = [{**p, 'author': get_author(p['url'])} for p in pages]
pages = [p.update(author=get_author(p['url'])) or p for p in pages]
Since p.update() returns None, None or p
will always be the updated version of p.
The first one seems to be more readable but I believe that the second one beats the first one in performance.
我不确定,但是以下方法可能有效:
[pages[index]['author'] = get_author(page['url']) for index, page in enumerate(pages)]
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.