python - subcadenas - Dividir cadena cada n caracteres?
string en python (23)
¿Es posible dividir una cadena de python cada n caracteres?
Por ejemplo, supongamos que tengo una cadena que contiene lo siguiente:
''1234567890''
¿Cómo puedo conseguir que se vea así?
[''12'',''34'',''56'',''78'',''90'']
Una función para mostrar un grupo de cadenas
def display(list):
for i in list: #To display the strings
print(i)
#Take a group of strings from keyboard
print(''Enter strings separated by comma: '')
list = [x for x in input().split(",")]
#call display() and pass the list
display(list)
#output
karthik, siva, raman, inban
Enter strings separated by comma:
karthik
siva
raman
inban
Aquí está mi solución:
def split_every(n, s):
return [ s[i:i+n] for i in xrange(0, len(s), n) ]
print split_every(2, "1234567890")
Aquí hay otra solución para un caso más general donde los trozos no son de igual longitud. Si la longitud es 0, se devuelve toda la parte restante.
data
es la secuencia a dividir; fieldsize
es una tupla con la lista de la longitud del campo.
def fieldsplit(data=None, fieldsize=()):
tmpl=[];
for pp in fieldsize:
if(pp>0):
tmpl.append(line[:pp]);
line=line[pp:];
else:
tmpl.append(line);
break;
return tuple(tmpl);
Como siempre, para los que aman los liners.
n = 2
line = "this is a line split into n characters"
line = [line[i * n:i * n+n] for i,blah in enumerate(line[::n])]
Creo que esto es más corto y más legible que la versión de itertools:
def split_by_n( seq, n ):
"""A generator to divide a sequence into chunks of n units."""
while seq:
yield seq[:n]
seq = seq[n:]
print list(split_by_n("1234567890",2))
Estoy usando esto:
list(''''.join(s) for s in zip(my_str[::2], my_str[1::2]))
o puedes usar cualquier otro número n
lugar de 2
.
Me gusta esta solución:
s = ''1234567890''
o = []
while s:
o.append(s[:2])
s = s[2:]
Otra forma común de agrupar elementos en grupos de n longitud:
>>> s = ''1234567890''
>>> map(''''.join, zip(*[iter(s)]*2))
[''12'', ''34'', ''56'', ''78'', ''90'']
Este método viene directamente de los documentos para zip()
.
Prueba el siguiente código:
from itertools import islice
def split_every(n, iterable):
i = iter(iterable)
piece = list(islice(i, n))
while piece:
yield piece
piece = list(islice(i, n))
s = ''1234567890''
print list(split_every(2, list(s)))
Prueba esto:
s=''1234567890''
print([s[idx:idx+2] for idx,val in enumerate(s) if idx%2 == 0])
Salida:
[''12'', ''34'', ''56'', ''78'', ''90'']
Sé que esta pregunta es antigua, pero esta es la forma más corta de hacerlo que conozco:
def split_every_n(S, n):
return [S[i*n:(i+1)*n] for i in range(len(S) / n)]
Esto, sin embargo, asume que la longitud de su cadena es un múltiplo de n. De lo contrario, tendrías que rellenarla.
Solo para completar, puedes hacer esto con una expresión regular:
>>> import re
>>> re.findall(''..'',''1234567890'')
[''12'', ''34'', ''56'', ''78'', ''90'']
Como se señala en el comentario, puedes hacer esto:
>>> import re
>>> re.findall(''..?'', ''123456789'')
[''12'', ''34'', ''56'', ''78'', ''9'']
También puede hacer lo siguiente, para simplificar la expresión regular para trozos más largos:
>>> import re
>>> re.findall(''.{1,2}'', ''123456789'')
[''12'', ''34'', ''56'', ''78'', ''9'']
Y puede usar re.finditer
si la cadena es larga para generar un trozo por otro.
Spooky one - intentó inventar otra respuesta más:
def split(s, chunk_size):
a = zip(*[s[i::chunk_size] for i in range(chunk_size)])
return [''''.join(t) for t in a]
print(split(''1234567890'', 1))
print(split(''1234567890'', 2))
print(split(''1234567890'', 3))
Afuera
[''1'', ''2'', ''3'', ''4'', ''5'', ''6'', ''7'', ''8'', ''9'', ''0'']
[''12'', ''34'', ''56'', ''78'', ''90'']
[''123'', ''456'', ''789'']
Tengo este código que uso cuando necesito hacer esto:
def split_string(n, st):
lst = [""]
for i in str(st):
l = len(lst) - 1
if len(lst[l]) < n:
lst[l] += i
else:
lst += [i]
return lst
print(split_string(3, "test_string."))
Dónde:
-
n
es la longitud de cada elemento de la lista -
st
es la cadena a dividir -
lst
es la versión de lista dest
-
i
es el caracter actual que se usa enst
-
l
es la longitud del último elemento de la lista
Una solución recursiva simple para cadena corta:
def split(s, n):
if len(s) < n:
return []
else:
return [s[:n]] + split(s[n:], n)
print(split(''1234567890'', 2))
O en tal forma:
def split(s, n):
if len(s) < n:
return []
elif len(s) == n:
return [s]
else:
return split(s[:n], n) + split(s[n:], n)
, que ilustra el patrón típico de división y conquista en el enfoque recursivo de manera más explícita (aunque en la práctica no es necesario hacerlo de esta manera)
Usando more-itertools de PyPI:
>>> from more_itertools import sliced
>>> list(sliced(''1234567890'', 2))
[''12'', ''34'', ''56'', ''78'', ''90'']
Usando lambda:
split_string = lambda x, n: [x[i:i+n] for i in range(0, len(x), n)]
s = ''1234567890''
split_string(s,2)
[''12'', ''34'', ''56'', ''78'', ''90'']
Utilizar itertools
La sección "Recipes" del manual proporciona una función para hacer exactamente esto:
def grouper(iterable, n, fillvalue=None):
"Collect data into fixed-length chunks or blocks"
# grouper(''ABCDEFG'', 3, ''x'') --> ABC DEF Gxx
args = [iter(iterable)] * n
return izip_longest(fillvalue=fillvalue, *args)
more_itertools.sliced
ha sido mentioned anteriormente. Aquí hay cuatro opciones más de la biblioteca more_itertools
:
s = "1234567890"
["".join(c) for c in mit.grouper(2, s)]
["".join(c) for c in mit.chunked(s, 2)]
["".join(c) for c in mit.windowed(s, 2, step=2)]
["".join(c) for c in mit.split_after(s, lambda x: int(x) % 2 == 0)]
Cada una de las últimas opciones produce el siguiente resultado:
[''12'', ''34'', ''56'', ''78'', ''90'']
Documentación para las opciones discutidas: chunked
, chunked
, con windowed
, split_after
>>> from functools import reduce
>>> from operator import add
>>> from itertools import izip
>>> x = iter(''1234567890'')
>>> [reduce(add, tup) for tup in izip(x, x)]
[''12'', ''34'', ''56'', ''78'', ''90'']
>>> x = iter(''1234567890'')
>>> [reduce(add, tup) for tup in izip(x, x, x)]
[''123'', ''456'', ''789'']
>>> from textwrap import wrap
>>> s = ''1234567890''
>>> wrap(s, 2)
[''12'', ''34'', ''56'', ''78'', ''90'']
Esto es lo que dice el docstring for wrap:
>>> help(wrap)
''''''
Help on function wrap in module textwrap:
wrap(text, width=70, **kwargs)
Wrap a single paragraph of text, returning a list of wrapped lines.
Reformat the single paragraph in ''text'' so it fits in lines of no
more than ''width'' columns, and return a list of wrapped lines. By
default, tabs in ''text'' are expanded with string.expandtabs(), and
all other whitespace characters (including newline) are converted to
space. See TextWrapper class for available keyword args to customize
wrapping behaviour.
''''''
>>> line = ''1234567890''
>>> n = 2
>>> [line[i:i+n] for i in range(0, len(line), n)]
[''12'', ''34'', ''56'', ''78'', ''90'']
def split(s, n):
"""
Split string every nth character
Parameters
----------
s: string
n: value of nth
"""
new_list = []
for i in range(0, len(s), n):
new_list.append(s[i:i+n])
return new_list
print(split(''1234567890'', 2))