我在玩弄python中的zip()函数,发现在使用for循环时遇到问题。这是我的代码:
list1 = ['monday', 'tuesday', 'wednesday', 'thursday'] list2 = [1, 2, 3, 4] zipped_list = zip(list1, list2) print(*zipped_list) # unpacked zipped list for a, b in zipped_list: # for this to work comment the print(*zipped_list) statement print(a, b)
该代码的输出为:
('monday', 1) ('tuesday', 2) ('wednesday', 3) ('thursday', 4) Process finished with exit code 0
现在,如果删除了print(* zipped_list)语句,则可以正确执行for循环:
monday 1 tuesday 2 wednesday 3 thursday 4 Process finished with exit code 0
为什么会这样呢?
如第一个注释中指出的,zip对象与first一起使用print(*zipped_list)
。但是,您可以先将zip对象转换为列表,这样便可以再次使用zip对象的值:
zipped_list = list(zip(list1, list2))
zip对象是Iterator
。链接中的这个Q / A应该解释为什么会这样:
问:什么时候需要额外的迭代器?
答:迭代器通常需要维护某种位置状态信息(例如返回的最后一个元素的索引等)。如果iterable本身保持该状态,则它本质上将成为不可重入的(意味着您一次只能使用一个循环)。
还可以看看zip的文档。邮递区号等于:
def zip(*iterables): # zip('ABCD', 'xy') --> Ax By sentinel = object() iterators = [iter(it) for it in iterables] while iterators: result = [] for it in iterators: elem = next(it, sentinel) if elem is sentinel: return result.append(elem) yield tuple(result)
看到收益声明了吗?这使其成为类似对象的生成器。因此,遍历它会耗尽它。请注意,仅打印zip对象也会耗尽它。
由于zip对象就像生成器一样,它们按需生成元素,而不是将整个列表扩展到内存中。这样做的好处是在典型的用例中效率更高。