繁体   English   中英

使用另一个生成器的生成器理解

[英]Generator comprehension using another generator

我正在尝试编写一个返回Generator的方法。 这两种方法的最终结果是得到以下形式的两个列表的组合: 'A #1', 'B #1', ..., 'F #9'

FLATS = ['A', 'B', 'C', 'D', 'E', 'F']

def generate_nums() -> Generator[str, None, None]:
    prefix = '#'
    for num in range(10):
        code = ''.join([prefix, str(num)])

        yield code

def generate_room_numbers() -> Generator[str, None, None]:
    room_nums = generate_nums()

    yield (' '.join([flat_name, room_num]) for room_num in room_nums for flat_name in FLATS)

if __name__ == "__main__":
    result = generate_room_numbers()
    result = next(result) # I hate this. How do I get rid of this?
    for room in result:
        print(room)

这给了我正确的结果。 虽然,我的烦恼是行result = next(result) 有一个更好的方法吗? 我查看了这个答案以及yield from syntax 但我几乎不能完全理解生成器。

您可以使用生成器表达式和 f 字符串:


FLATS = ['A', 'B', 'C', 'D', 'E', 'F']
room_numbers = (f'{letter} #{i}' for i in range(1, 10) for letter in FLATS)

for room in room_numbers:
    print(room)

Output:

A #1
B #1
C #1
.
.
.
D #9
E #9
F #9

最好将yield语句放在显式循环中,而不是尝试生成生成器。

你的generate_room_numbers应该是这样的:

def generate_room_numbers():
    for flat_name in FLATS:
        room_nums = generate_nums()
        for room_num in room_nums:    
            yield (' '.join([flat_name, room_num]))

请注意, generate_nums()是在flat_name循环调用的,因为您不能重复迭代它返回的同一个迭代器; 在遍历它之后,它被耗尽并且generate_nums每次都会引发StopIteration (以便迭代产生一个空序列)。

(如果generate_nums很昂贵,那么你当然可以在flat_name循环之外执行nums = list(generate_nums())然后在循环内迭代它,但是如果这可能需要很多 memory,那么它可能会击败大部分点首先使用生成器。)

您的代码的 rest 除了主代码中的result = next(result)被删除之外没有变化,但是为了方便起见,这里是整个事情:

FLATS = ['A', 'B', 'C', 'D', 'E', 'F']

def generate_nums():
    prefix = '#'
    for num in range(10):
        code = ''.join([prefix, str(num)])

        yield code

def generate_room_numbers():
    for flat_name in FLATS:
        room_nums = generate_nums()
        for room_num in room_nums:    
            yield (' '.join([flat_name, room_num]))

if __name__ == "__main__":
    result = generate_room_numbers()
    # result = next(result)  <<==== NOT NEEDED ANY MORE
    for room in result:
        print(room)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM