有人能解释一下,为什么遍历由迭代器X生成的列表会产生与遍历迭代器X不同的结果?你知道吗
换句话说[x代表列表中的x(IteratorObject)]!=[x表示迭代器对象中的x]
>>> randoms = [random.randrange(10) for i in range(100)]
>>> [ (x[0],list(x[1])) for x in itertools.groupby(sorted(randoms))]
[(0, [0, 0, 0, 0, 0, 0, 0, 0]), (1, [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]), (2, [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]), (3, [3, 3, 3, 3, 3, 3]), (4, [4, 4, 4, 4, 4, 4, 4, 4, 4, 4]), (5, [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5]), (6, [6, 6, 6, 6, 6, 6, 6, 6, 6]), (7, [7, 7, 7, 7, 7]), (8, [8, 8, 8, 8, 8, 8, 8]), (9, [9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9])]
>>> [ (x[0],list(x[1])) for x in list(itertools.groupby(sorted(randoms)))]
[(0, []), (1, []), (2, []), (3, []), (4, []), (5, []), (6, []), (7, []), (8, []), (9, [9])]
>>> sys.version
'3.3.3 (default, Dec 2 2013, 01:40:21) \n[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.2.79)]'
我认为文档中的这一点解释了问题:
“返回的组本身是一个迭代器,它与groupby()共享基础iterable。因为源是共享的,所以当groupby()对象处于高级时,上一个组将不再可见。因此,如果以后需要这些数据,应该将其存储为列表”
在第二个示例中,当您转换为列表时,会立即遍历所有组。但是在每个组中,您不会遍历底层元素。当您最终尝试使用list(x[1])执行此操作时,为时已晚—您已经耗尽了迭代器。你知道吗
从
itertools.groupby
为每个组生成的迭代器并不独立于顶级迭代。在进入下一个组之前,您需要使用它们中的每一个,否则迭代器将变得无效(它将不再产生任何结果)。你知道吗此行为在the docs中引用:
你的两个清单说明了这一点。在第一个函数中,调用
list
onx[1]
,这是迭代器。在第二个版本中,所有迭代器首先在list
调用中围绕groupby
调用生成,并且只有在遍历该列表时,内部迭代器才会被使用。请注意,最后一个组([9]
)上的迭代器确实有效!你知道吗下面是一个简单的例子:
相关问题 更多 >
编程相关推荐