[英]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.