Reputation: 8827
Let's say, we have and list of objects in variable called "articles", each object has a member "tags" (which is simple list).
Expected output: all tags in all articles, joined in a single list.
In multiple lines, solution would be:
arr = []
for article in articles:
for tag in article.tags:
arr.append(tag)
Now, how can we write this in single line instead of 4?
This syntax is invalid:
arr = [tag for tag in article.tags for article in articles]
Thanks!
Upvotes: 4
Views: 5626
Reputation: 56714
If you want unique tags, you might be better served by
import operator
tags = reduce(operator.__or__, (set(article.tags) for article in articles), set())
Edit:
For Python 3, you would need to
from functools import reduce
The initializer set()
is returned if the sequence is empty, rather than throwing an error.
Upvotes: 2
Reputation: 5725
This is already answered multiple times, but it can be helpful to break lines and indent:
arr = [tag
for article in articles
for tag in article.tags]
This has the advantage of
(tag.name, tag.description, tag.count)
or some other tuple or transformation of a tag) Upvotes: 2
Reputation: 6987
Try this:
import itertools
it = itertools.chain.from_iterable(article.tags for article in articles)
l = list(it) # if you really need a list and not an iterator
Upvotes: 2
Reputation: 64177
You are actually looping in the order that you don't want to order:
what you want is:
result = [ tag for article in articles for tag in article.tags ]
To translate what you were doing in your example would be:
for tag in article.tags:
for article in articles:
#code
which doesn't make much sense.
Upvotes: 5
Reputation: 799520
It's invalid because article
doesn't exist by the time the first loop is parsed.
arr = [tag for article in articles for tag in article.tags]
Upvotes: 11