Python的yield语句每次都返回相同的值

问题描述 投票:0回答:1

EDIT: 我想看看使用的解决方案。next 语句.我正在访问一个天气应用API,返回一个json对象,该对象的一部分信息是每天的日出日落时间,这里是它的内容(三天)。

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"
    }
]
}

这里是函数,它应该每天返回一个元组,但它没有。它一直返回同一天的数据元组,也就是第一天。

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)))

这里是输出结果。

('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')
python yield next
1个回答
6
投票

因为你每次循环都要启动生成器,而不是循环一个范围就迭代生成器。

for rise, set in forecast(daily_return):
    print(rise, set)

如果你只想要前3个,你可以用一个范围来压缩它,或者使用 itertools.islice 如 @cs95 所示。

for rise, set, _ in zip(forecast(daily_return), range(3)):
    print(rise, set)

如果你必须使用 next 然后在回路外启动发电机。

gen = forecast(daily_return)
for i in range(3):
    print(next(gen))

你也可以用 operator.itemgetter 来实现同样的功能,而不是你的自定义功能。

from operator import itemgetter
from itertools import islice

forecast_gen = map(itemgetter('sunrise', 'sunset'), daily_return)

for rise, set in islice(forecast_gen, 3):
    print(rise, set)

2
投票

我建议将 forecast 到一个对单个条目进行操作的函数。然后你可以调用 map 来获得一个迭代器并调用 next 上。

def forecast(day):
    return day['sunrise'], day['sunset']

it = map(forecast, daily_return)
print(next(it))
# ('2020-06-10 05:09:15+01:00', '2020-06-10 19:47:50+01:00')

如果你想从迭代器中得到X个条目,就用... islice:

from itertools import islice
list(islice(map(forecast, daily_return), 3))
# [('2020-06-10 05:09:15+01:00', '2020-06-10 19:47:50+01:00'),
#  ('2020-06-11 05:09:11+01:00', '2020-06-11 19:48:17+01:00'),
#  ('2020-06-12 05:09:08+01:00', '2020-06-12 19:48:43+01:00')]

0
投票

你重新创建3次生成器,然后3次产生相同的第一个元素。在循环之前创建生成器。简单的比复杂的好。

x = forecast(daily_return))
for i in range(3):
    print(next(x))
© www.soinside.com 2019 - 2024. All rights reserved.