valores una renombrar reemplazar normalizar eliminar datos data columnas columna borrar agregar python iteration

python - una - reemplazar valores pandas



Iterar sobre una cadena 2(o n) caracteres a la vez en Python (12)

Antes de hoy, tenía que recorrer una secuencia de 2 caracteres a la vez para analizar una cadena formateada como "+c-R+DE" (hay algunas letras adicionales).

Terminé con esto, que funciona, pero se ve feo. Terminé comentando lo que estaba haciendo porque no era obvio. Casi parece pitón, pero no del todo.

# Might not be exact, but you get the idea, use the step # parameter of range() and slicing to grab 2 chars at a time s = "+c-R+D-e" for op, code in (s[i:i+2] for i in range(0, len(s), 2)): print op, code

¿Hay alguna forma mejor / más limpia de hacer esto?


Aquí está mi respuesta, un poco más limpia a mis ojos:

for i in range(0, len(string) - 1): if i % 2 == 0: print string[i:i+2]


Considere la posibilidad de instalar pip more_itertools , que ya viene con una implementación chunked junto con otras herramientas útiles:

import more_itertools for op, code in more_itertools.chunked(s, 2): print(op, code)

Salida:

+ c - R + D - e


Este enfoque admite un número arbitrario de elementos por resultado, evalúa perezosamente y la entrada iterable puede ser un generador (no se intenta indexar):

import itertools def groups_of_n(n, iterable): c = itertools.count() for _, gen in itertools.groupby(iterable, lambda x: c.next() / n): yield gen

Cualquier elemento restante se devuelve en una lista más corta.

Ejemplo de uso:

for g in groups_of_n(4, xrange(21)): print list(g) [0, 1, 2, 3] [4, 5, 6, 7] [8, 9, 10, 11] [12, 13, 14, 15] [16, 17, 18, 19] [20]


Gran oportunidad para un generador. Para listas más grandes, esto será mucho más eficiente que comprimir todos los demás elementos. Tenga en cuenta que esta versión también maneja cadenas con op colgantes.

def opcodes(s): while True: try: op = s[0] code = s[1] s = s[2:] except IndexError: return yield op,code for op,code in opcodes("+c-R+D-e"): print op,code

edición: reescritura secundaria para evitar excepciones de ValueError.


Las otras respuestas funcionan bien para n = 2, pero para el caso general, puede intentar esto:

def slicen(s, n, truncate=False): nslices = len(s) / n if not truncate and (len(s) % n): nslices += 1 return (s[i*n:n*(i+1)] for i in range(nslices)) >>> s = ''+c-R+D-e'' >>> for op, code in slicen(s, 2): ... print op, code ... + c - R + D - e >>> for a, b, c in slicen(s, 3): ... print a, b, c ... + c - R + D Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: need more than 2 values to unpack >>> for a, b, c in slicen(s,3,True): ... print a, b, c ... + c - R + D


Me encontré con un problema similar. Terminé haciendo algo como esto:

ops = iter("+c-R+D-e") for op in ops code = ops.next() print op, code

Sentí que era lo más legible.


No sé sobre limpiador, pero hay otra alternativa:

for (op, code) in zip(s[0::2], s[1::2]): print op, code

Una versión sin copia:

from itertools import izip, islice for (op, code) in izip(islice(s, 0, None, 2), islice(s, 1, None, 2)): print op, code


Quizás no sea el más eficiente, pero si te gustan las expresiones regulares ...

import re s = "+c-R+D-e" for op, code in re.findall(''(.)(.)'', s): print op, code


Tal vez esto sería más limpio?

s = "+c-R+D-e" for i in xrange(0, len(s), 2): op, code = s[i:i+2] print op, code

Tal vez podrías escribir un generador para hacer lo que quieras, tal vez eso sería más pitónico :)


Triptych inspiró esta solución más general:

def slicen(s, n, truncate=False): assert n > 0 while len(s) >= n: yield s[:n] s = s[n:] if len(s) and not truncate: yield s for op, code in slicen("+c-R+D-e", 2): print op,code


>>> s = "+c-R+D-e" >>> s ''+c-R+D-e'' >>> s[::2] ''+-+-'' >>>


from itertools import izip_longest def grouper(iterable, n, fillvalue=None): args = [iter(iterable)] * n return izip_longest(*args, fillvalue=fillvalue) def main(): s = "+c-R+D-e" for item in grouper(s, 2): print '' ''.join(item) if __name__ == "__main__": main() ##output ##+ c ##- R ##+ D ##- e

izip_longest requiere Python 2.6 (o superior). Si está en Python 2.4 o 2.5, use la definición de izip_longest del document o cambie la función de izip_longest a:

from itertools import izip, chain, repeat def grouper(iterable, n, padvalue=None): return izip(*[chain(iterable, repeat(padvalue, n-1))]*n)