List description
When I first started by understanding the list, I read it like English sentences, and I could easily understand them. For example,
[item for sublist in list_of_lists for item in sublist]
can be read as
for each sublist in list_of_lists and for each item in sublist add item
In addition, the filter part can be read as
for each sublist in list_of_lists and for each item in sublist add item only if it is valid
And the corresponding understanding will be
[item for sublist in list_of_lists for item in sublist if valid(item)]
Generators
They are similar to land mines that fire only when called with the next protocol. They are similar to functions, but until an exception is thrown or the end of the function is reached, they are not exhausted, and they can be called again and again. The important thing is that they maintain state between the previous call and the current one.
The difference between a generator and a function is that generators use the yield keyword to return the value to the caller. In the case of a generator expression, they are similar to list comprehension; a fist expression is the actual value that is “given”.
In this basic understanding, if we look at your expressions in a question,
[(item for sublist in list_of_lists) for item in sublist]
You mix list comprehension with generator expressions. It will be read as follows
for each item in sublist add a generator expression which is defined as, for every sublist in list_of_lists yield item
this is not what you had in mind. And since the generator expression is not iterated, the generator expression object is added to the list as is. Since they will not be evaluated without calling with the following protocol, they will not cause errors (if they are, if they do not have a syntax error). In this case, it will throw a runtime error because the sublist is not yet defined.
In addition, in the latter case
[item for sublist in (list_of_lists for item in sublist)]
for each sublist in the generator expression, add item and the generator expression is defined as for each item in sublist yield list_of_lists.
The for loop will iterate over any iterative using the following protocol. That way, the generator expression will be evaluated, and item will always be the last item in the iteration of the sublist , and you add this to the list. This will also cause a runtime error since the subscriptions are not yet defined.