EDIT: I want to see the solution using the next
statement.
I am accessing a weather app API that returns a json object, a part of the information of that object is the daily time of sunrise and sunset, here is its content (for three days):
my_dict = {
"daily": [
{
"dt": "2020-06-10 12:00:00+01:00",
"sunrise": "2020-06-10 05:09:15+01:00",
"sunset": "2020-06-10 19:47:50+01:00"
},
{
"dt": "2020-06-11 12:00:00+01:00",
"sunrise": "2020-06-11 05:09:11+01:00",
"sunset": "2020-06-11 19:48:17+01:00"
},
{
"dt": "2020-06-12 12:00:00+01:00",
"sunrise": "2020-06-12 05:09:08+01:00",
"sunset": "2020-06-12 19:48:43+01:00"
}
]
}
And here is the function that should return a tuple per day, but it does not. It keeps returning a tuple of data for the same day, the first day.
daily_return = my_dict['daily']
def forecast(daily_return):
# daily_return is a list
for day in daily_return:
# day becomes a dict
sunrise = day['sunrise']
sunset = day['sunset']
yield sunrise, sunset
for i in range(3):
print(next(forecast(daily_return)))
And here is the output:
('2020-06-10 05:09:15+01:00', '2020-06-10 19:47:50+01:00')
('2020-06-10 05:09:15+01:00', '2020-06-10 19:47:50+01:00')
('2020-06-10 05:09:15+01:00', '2020-06-10 19:47:50+01:00')
Because you're initiating the generator every time you loop instead of looping a range just iterate the generator:
for sunrise, sunset in forecast(daily_return):
print(sunrise, sunset)
If you only want the first 3 you can zip it with a range or use itertools.islice
as @cs95 has shown:
for sunrise, sunset, _ in zip(forecast(daily_return), range(3)):
print(rise, set)
If you must use next
then initiate the generator outside the loop:
gen = forecast(daily_return)
for i in range(3):
print(next(gen))
You can also use operator.itemgetter
to achieve this same functionality instead of your custom function:
from operator import itemgetter
from itertools import islice
forecast_gen = map(itemgetter('sunrise', 'sunset'), daily_return)
for sunrise, sunset in islice(forecast_gen, 3):
print(sunrise, sunset)