Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

281
Vistas
zip_longest para la lista de la izquierda siempre

Conozco la función zip (que se comprimirá de acuerdo con la lista más corta) y zip_longest (que se comprimirá de acuerdo con la lista más larga), pero ¿cómo puedo comprimir de acuerdo con la primera lista, independientemente de si es la más larga o no?

Por ejemplo:

 Input: ['a', 'b', 'c'], [1, 2] Output: [('a', 1), ('b', 2), ('c', None)]

Pero también:

 Input: ['a', 'b'], [1, 2, 3] Output: [('a', 1), ('b', 2)]

¿Existen ambas funcionalidades en una función?

over 4 years ago · Santiago Trujillo
9 Respuestas
Responde la pregunta

0

Aquí hay otra toma, si el objetivo es un código legible y fácil de entender:

 def zip_first(first, *rest, fillvalue=None): rest = [iter(r) for r in rest] for x in first: yield x, *(next(r, fillvalue) for r in rest)

Esto usa la forma de dos argumentos de next() para devolver el valor de relleno para todos los iterables que están agotados.

Para exactamente dos iterables, esto se puede simplificar a

 def zip_first(first, second, fillvalue=None): second = iter(second) for x in first: yield x, next(second, fillvalue)
over 4 years ago · Santiago Trujillo Denunciar

0

Devuelve solo los elementos len(a) de zip_longest :

 from itertools import zip_longest def zip_first(a, b): z = zip_longest(a, b) for i, r in zip(range(len(a)), z): yield r
over 4 years ago · Santiago Trujillo Denunciar

0

Un poco feo, pero me quedaría con este. La idea es acortar la segunda lista al tamaño de la primera si es más larga. Luego usamos zip_longest para garantizar que el resultado sea al menos tan largo como el primer argumento de zip .

 import itertools input1 = [['a', 'b', 'c'], [1, 2]] input2 = [['a', 'b'], [1, 2, 3]] zip1 = itertools.zip_longest(input1[0], input1[1][:len(input1[0])]) zip2 = itertools.zip_longest(input2[0], input2[1][:len(input2[0])]) print(list(zip1)) print(list(zip2))

Producción:

 [('a', 1), ('b', 2), ('c', None)] [('a', 1), ('b', 2)]

Para comprimir varias listas, esto se puede usar:

 import itertools def zip_first(lists): equal_lists = [l[:len(lists[0])] for l in lists] return itertools.zip_longest(*equal_lists)
over 4 years ago · Santiago Trujillo Denunciar

0

No conozco uno readymade, pero puedes definir el tuyo propio.

El uso de object() como centinela garantiza que siempre se probará como único y nunca se confundirá con None o cualquier otro valor de relleno. Por lo tanto, esto debería comportarse correctamente incluso si alguno de sus iterables contiene None .

Al igual que zip_longest , toma cualquier número de iterables (no necesariamente dos) y puede especificar el valor de fillvalue .

 from itertools import zip_longest def zip_left(*iterables, fillvalue=None): SENTINEL = object() for first, *others in zip_longest(*iterables, fillvalue=SENTINEL): if first is SENTINEL: return others = [i if i is not SENTINEL else fillvalue for i in others] yield (first, *others) print(list(zip_left(['a', 'b', 'c'], [1, 2]))) print(list(zip_left(['a', 'b'], [1, 2, 3])))

Producción:

 [('a', 1), ('b', 2), ('c', None)] [('a', 1), ('b', 2)]
over 4 years ago · Santiago Trujillo Denunciar

0

Para iteradores genéricos (o listas también), puede usar esto. Obtenemos pares hasta que llegamos a StopIteration en a . Si presionamos StopIteration en b primero, usamos None como el segundo valor.

 def zip_first(a, b): ai, bi = iter(a), iter(b) while True: try: aa = next(ai) except StopIteration: return try: bb = next(bi) except StopIteration: bb = None yield aa, bb
over 4 years ago · Santiago Trujillo Denunciar

0

Puede reutilizar el código python "más o menos equivalente" que se muestra en los documentos para itertools.zip_longest para hacer una versión generalizada que se comprima según la longitud del primer argumento:

 from itertools import repeat def zip_by_first(*args, fillvalue=None): # zip_by_first('ABCD', 'xy', fillvalue='-') --> Ax By C- D- # zip_by_first('ABC', 'xyzw', fillvalue='-') --> Ax By Cz if not args: return iterators = [iter(it) for it in args] while True: values = [] for i, it in enumerate(iterators): try: value = next(it) except StopIteration: if i == 0: return iterators[i] = repeat(fillvalue) value = fillvalue values.append(value) yield tuple(values)

Es posible que pueda realizar algunas pequeñas mejoras, como almacenar en caché repeat(fillvalue) o menos. El problema con esta implementación es que está escrita en Python, mientras que la mayoría de itertools usa una implementación C mucho más rápida. Puede ver los efectos de esto comparándolo con la respuesta de Kelly Bundy .

over 4 years ago · Santiago Trujillo Denunciar

0

Si las entradas son listas (u otras colecciones que se pueden usar con len ), puede usar zip_longest y limitar perezosamente el resultado a la longitud de la primera lista 1 , usando islice :

 from itertools import islice, zip_longest def zip_first(a, b): return islice(zip_longest(a, b), len(a))

1 Esta idea básica fue tomada de la respuesta de Jan Christoph Terasa .

over 4 years ago · Santiago Trujillo Denunciar

0

no se pero

 first = ['a', 'b', 'c'] last = [1, 2, 3, 4] if len(first) < len(last): b = list(zip(first, last)) else: b = list(zip_longest(first, last)) print(b)
over 4 years ago · Santiago Trujillo Denunciar

0

Haga que el segundo sea infinito y luego use el zip normal:

 from itertools import chain, repeat a = ['a', 'b', 'c'] b = [1, 2] b = chain(b, repeat(None)) print(*zip(a, b))
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda