Using this simple loop, I print a bunch of numbers:
rows = cursor.execute.....
rows_ftcl = rows.fetchall()
for row in rows_ftcl:
test = row[2]
print(test)
I would like to use the same loop with "Short Hand", written in the same row in a variable, and get the same result. I would use something like this:
rows = cursor.execute.....
rows_ftcl = rows.fetchall()
test = row[2] for row in rows_ftcl
print(test)
If I use this though, I get the error <generator object <genexpr> at 0x7effb5f1edc0>
. I also tried adding the square brackets and i get the print in a list. I don't want to print in a list, but i want to print the numbers vertically (without any brackets).
How can I get the same result as above loop? I would like to use "Short Hand" mode, writing everything in the same line (like my second example)
CodePudding user response:
<generator object <genexpr> at 0x7effb5f1edc0>
is not an error. It is just the string representation of the generator object created by the expression row[2] for row in rows_ftcl
. If you don't know what a generator is, many good explanations are a quick web search away
Now, you want to print all elements that are yielded by this generator. To do this, you first need to build the string that you will print. You didn't need to do this in the previous approach because you simply looped over the elements of the generator, and printed them one-by-one. The print
implicitly ended each call to it with the newline character "\n"
. Since you're going to have to build the string yourself, you'll have to put these in yourself. We can do this by joining all the elements that the generator yields by the newline character.
# Join on newline ┌ join needs each element to be a string
# | |
# v v
text = "\n".join(str(row[2]) for row in rows_ftcl)
print(text)
Alternatively, unpack that generator into the arguments for print
, and pass a newline character as the separator argument. Now print
behaves as if each element of the generator was a separate argument, and uses the characters specified in sep
to separate each argument when it prints them out
test = (row[2] for row in rows_ftcl)
print(*test, sep="\n")
CodePudding user response:
A generator is an iterable. And just like any other iterable, it can be used as the target of the unpack, or splat, operator
An asterisk
*
denotes iterable unpacking. Its operand must be an iterable. The iterable is expanded into a sequence of items, which are included in the new tuple, list, or set, at the site of the unpacking.
So we can use the unpack operator to pass all of the generator's values as arguments to print
. Then we choose a separator with the sep
keyword argument.
print(*(row[2] for row in rows_ftcl), sep='\n')
The extra parentheses around the generator expression are just for operator precedence; they have no special behavior on their own other than changing the parse order.