-1

I have a question regarding the differences between yield and yield from, particularly when they are used in combine with islice. Here is my code:

def get_table_row():
  iter_veh = get_data(fp_vehicle, vehicles_cols, Vehicles)
  iter_per = get_data(fp_personal, personals_cols, Personals)
  iter_emp = get_data(fp_employment, employments_cols, Employments)
  iter_upd = get_data(fp_update, updates_cols, Updates)
  yield from ((*v, *p, *e, *u) for v, p, e, u in zip(iter_veh, iter_per, iter_emp, iter_upd))

from itertools import islice
for row in islice(get_table_row(), 5):
  print(*row)

This will correctly print out 5 rows of records from the table.

HOWEVER, if I use the following code:

def get_table_row():
  iter_veh = get_data(fp_vehicle, vehicles_cols, Vehicles)
  iter_per = get_data(fp_personal, personals_cols, Personals)
  iter_emp = get_data(fp_employment, employments_cols, Employments)
  iter_upd = get_data(fp_update, updates_cols, Updates)
  yield ((*v, *p, *e, *u) for v, p, e, u in zip(iter_veh, iter_per, iter_emp, iter_upd))

from itertools import islice
for row in islice(get_table_row(), 5):
  print(*row)

This will lead to print out of all rows. The only difference here is yield from vs. yield. Need a explanation. Thanks!

Gene Xu
  • 609
  • 1
  • 8
  • 18

2 Answers2

1

A bare yield provides its argument. A yield from provides elements from its argument.

yield (1, 2, 3) # provide entire tuple at once
yield from (1, 2, 3) # provide elements from the tuple 

You can think of yield from as yield plus iteration:

yield from (1, 2, 3)
# iteration style 
for element in (1, 2, 3):
    yield element

Note that yield from does more than iteration: it bridges between its argument and the calling scope. Signals such as generator.close() are passed on automatically, instead of needing manual propagation.

MisterMiyagi
  • 44,374
  • 10
  • 104
  • 119
1

The yield from statement (greatly simplified) will yield every item from the given iterator. Whereas the yield statement will yield a single value.

For this particular use-case you could replace yield from with the following lines of code:

for value in generator:
    yield value

Here's some more info about what yield from can do: In practice, what are the main uses for the new "yield from" syntax in Python 3.3?

Wolph
  • 78,177
  • 11
  • 137
  • 148