zip y groupby curiosidad en python 2.7

¿Alguien puede explicar por qué estos producen diferentes cosas en Python 2.7.4? Producen lo mismo en Python 3.3.1. Me pregunto si este es un error en 2.7 que se corrigió en 3, o si se debe a algún cambio en el idioma.

>>> for (i,j),k in zip(groupby([1,1,2,2,3,3]), [4,5,6]): ... print list(j) ... [] [] [3] >>> for i,j in groupby([1,1,2,2,3,3]): ... print list(j) ... [1, 1] [2, 2] [3, 3] 

Esto no es un error. Tiene que ver con cuando el grupo se agota. Prueba lo siguiente con python3 y verás el mismo comportamiento:

 from itertools import groupby for (i,j),k in list(zip(groupby([1,1,2,2,3,3]), [4,5,6])): print (i,list(j),k) 

Tenga en cuenta que si elimina la list externa, obtendrá el resultado que espera. El “problema” aquí es que el objeto de agrupador (devuelto en j ) es un iterable que produce elementos siempre que sean iguales. No sabe de antemano qué producirá ni cuántos elementos hay. Simplemente recibe un iterable como entrada y luego cede de ese iterable. Si pasa al siguiente “grupo”, lo iterable termina consumiéndose antes de que tenga la oportunidad de ver los elementos. Esta es una decisión de diseño para permitir que groupby opere en iterables que produzcan números de elementos arbitrarios (incluso infinitos).

En python2.x, zip creará una lista, moviéndose efectivamente más allá de cada “grupo” antes de que comience el ciclo. Al hacerlo, termina consumiendo cada uno de los objetos “grupales” devueltos por groupby . Es por esto que solo tiene el último elemento en la lista reportada. La solución para python2.x es usar itertools.izip lugar de zip . En python3.x, izip se convirtió en el zip integrado. Como lo veo, la única forma de admitir ambos en este script es a través de algo como:

 from __future__ import print_function from itertools import groupby try: from itertools import izip except ImportError: #python3.x izip = zip for (i,j),k in izip(groupby([1,1,2,2,3,3]), [4,5,6]): print (i,list(j),k)