Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
204 views
in Technique[技术] by (71.8m points)

outputs of different list comprehensions in python 3.x

I was studying about list comprehension in Python and I am confused why this two codes are producing different outputs. CODE:

print([(letter,num) for letter in 'abc' for num in range(2)])
print([((letter,num) for letter in 'abc') for num in range(2)])

OUTPUT:

[('a', 0), ('a', 1), ('a', 2), ('a', 3), ('b', 0), ('b', 1), ('b', 2), ('b', 3), ('c', 0), ('c', 1), ('c', 2), ('c', 3), ('d', 0), ('d', 1), ('d', 2), ('d', 3)]

[<generator object <listcomp>.<genexpr> at 0x000002919E020F20>, <generator object <listcomp>.<genexpr> at 0x000002919E148C10>, <generator object <listcomp>.<genexpr> at 0x000002919E1489E0>, <generator object <listcomp>.<genexpr> at 0x000002919E148C80>]

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The first example:

print([(letter,num) for letter in 'abc' for num in range(2)])

Prints a list (because of the outer [] brackets) which contains all the tuples (because of the parentheses around letter, num) of letter and num for each value of letter looping over 'abc' and each value of num looping over every value of the generator returned by range(2) (which will be 0 and 1).

Since Python takes the first for as the outer loop, you see ('a', 0), ('a', 1), etc. instead of ('a', 0), ('b', 0), etc.

However, when you add parentheses around a for expression like (letter,num) for letter in 'abc', you're no longer executing the loop in the comprehension, but you're capturing the generators (ready to start yielding their values, but not actually yielding the values into the comprehension).

So:

print([((letter,num) for letter in 'abc') for num in range(2)])

Here, ((letter,num) for letter in 'abc') is just a generator that will yield values as soon as you start asking for them.

Note: because the value of num is not enclosed in the generators separately, if you do something with them, you may see a surprising result:

x = [((letter,num) for letter in 'abc') for num in range(2)]
print(next(x[0]))
print(next(x[0]))
print(next(x[0]))
print(next(x[1]))
print(next(x[1]))
print(next(x[1]))

Result:

('a', 1)
('b', 1)
('c', 1)
('a', 1)
('b', 1)
('c', 1)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...