如何在不消耗生成器的情况下判断其是否为空?
Python生成器判断非空且不消耗元素的解决方案
问题描述
筛选场景中除玩家外的实体:
entities = filter(lambda entity: entity != player, location.entities)
尝试判断是否存在实体,若存在则逐个打印:
if any(entities): print('附近的实体:') for entity in entities: print(entity)
但any()会消耗生成器中的元素,导致后续for循环没有元素可迭代。需要在不转换为列表或手动重置迭代器的前提下,判断生成器是否为空或获取其长度。
可行方案
方案一:捕获第一个元素并继续遍历
直接尝试获取生成器的第一个元素,若成功则说明生成器非空,随后将第一个元素与剩余元素一起处理:
entities = filter(lambda entity: entity != player, location.entities) try: first_entity = next(entities) print('附近的实体:') print(first_entity) for entity in entities: print(entity) except StopIteration: # 生成器为空,无需操作 pass
这种方法无需转换为列表,仅需一次遍历,效率较高。
方案二:封装工具函数复用逻辑
自定义工具函数,缓存第一个元素并返回新的迭代器,方便复用:
def has_elements(iterator): try: first = next(iterator) return True, iter([first, *iterator]) except StopIteration: return False, iterator entities = filter(lambda entity: entity != player, location.entities) has_entities, entities = has_elements(entities) if has_entities: print('附近的实体:') for entity in entities: print(entity)
函数返回两个值:布尔值表示迭代器是否有元素,以及包含所有元素的新迭代器(包括被取出的第一个元素),确保后续遍历不丢失数据。
关键说明
生成器是一次性迭代的特性决定了:无法在不消耗任何元素的前提下判断是否为空——因为生成器的元素是按需生成的,必须取出至少一个元素才能确定是否有内容。上述方案都是通过取出第一个元素判断非空,同时保留该元素继续处理,避免数据丢失。
内容的提问来源于stack exchange,提问作者Michael Moreno
相关产品推荐
相关产品推荐

