python - Agregando espacios a la cadena basados en la lista
split (12)
Tengo la cadena y la matriz. Cadena tiene la misma cantidad de caracteres alfabéticos como matriz. Necesito dividir s para listar que tengan la misma longitud de cada elemento como arr.
s = ''Pythonisanprogramminglanguage''
arr = [''lkjhgf'', ''zx'', ''qw'', ''ertyuiopakk'', ''foacdhlc'']
expected == [''Python'', ''is'', ''an'', ''programming'', ''language'']
Aquí hay otro enfoque:
import numpy as np
ar = [0]+list(map(len, arr))
ar = list(np.cumsum(ar))
output_ = [s[i:ar[ar.index(i)+1]] for i in ar[:-1]]
Salida :
[''Python'', ''is'', ''an'', ''programming'', ''language'']
Cree un bucle simple y use la longitud de las palabras como su índice:
s = ''Pythonisanprogramminglanguage''
arr = [''lkjhgf'', ''zx'', ''qw'', ''ertyuiopakk'', ''foacdhlc'']
ctr = 0
words = []
for x in arr:
words.append(s[ctr:len(x) + ctr])
ctr += len(x)
print(words)
# [''Python'', ''is'', ''an'', ''programming'', ''language'']
El módulo de
itertools
tiene una función denominada
accumulate()
(agregada en Py 3.2) que ayuda a hacer esto relativamente fácil:
from itertools import accumulate # added in Py 3.2
s = ''Pythonisanprogramminglanguage''
arr = [''lkjhgf'', ''zx'', ''qw'', ''ertyuiopakk'', ''foacdhlc'']
cuts = tuple(accumulate(len(item) for item in arr))
words = [s[i:j] for i, j in zip((0,)+cuts, cuts)]
print(words) # -> [''Python'', ''is'', ''an'', ''programming'', ''language'']
En el futuro, un enfoque alternativo será usar una expresión de asignación (nueva en Python 3.8):
s = ''Pythonisanprogramminglanguage''
arr = [''lkjhgf'', ''zx'', ''qw'', ''ertyuiopakk'', ''foacdhlc'']
i = 0
expected = [s[i:(i := i+len(word))] for word in arr]
Es mucho más limpio usar
iter
con el
next
:
s = ''Pythonisanprogramminglanguage''
arr = [''lkjhgf'', ''zx'', ''qw'', ''ertyuiopakk'', ''foacdhlc'']
new_s = iter(s)
result = [''''.join(next(new_s) for _ in i) for i in arr]
Salida:
[''Python'', ''is'', ''an'', ''programming'', ''language'']
Otro enfoque más sería crear un patrón de expresiones regulares que describa la longitud deseada de las palabras.
Puedes reemplazar cada personaje por
.
(= cualquier caracter) y rodean las palabras con
()
:
arr = [''lkjhgf'', ''zx'', ''q'', ''ertyuiopakk'', ''foacdhlc'']
import re
pattern = ''('' + '')(''.join(re.sub(''.'', ''.'', word) for word in arr) + '')''
#=> ''(......)(..)(.)(...........)(........)''
Si el patrón coincide, obtienes las palabras deseadas en grupos directamente:
s = ''Pythonisaprogramminglanguage''
re.match(pattern, s).groups()
#=> (''Python'', ''is'', ''a'', ''programming'', ''language'')
Podrías recoger rebanadas del frente de
s
.
output = []
for word in arr:
i = len(word)
chunk, s = s[:i], s[i:]
output.append(chunk)
print(output) # -> [''Python'', ''is'', ''an'', ''programming'', ''language'']
Puede usar
itertools.accumulate
para obtener las posiciones donde desea dividir la cadena:
>>> s = ''Pythonisanprogramminglanguage''
>>> arr = [''lkjhgf'', ''zx'', ''qw'', ''ertyuiopakk'', ''foacdhlc'']
>>> import itertools
>>> L = list(itertools.accumulate(map(len, arr)))
>>> L
[6, 8, 10, 21, 29]
Ahora, si
zip
la lista, obtendrá los intervalos:
>>> list(zip([0]+L, L))
[(0, 6), (6, 8), (8, 10), (10, 21), (21, 29)]
Y solo tienes que usar los intervalos para dividir la cadena:
>>> [s[i:j] for i,j in zip([0]+L, L)]
[''Python'', ''is'', ''an'', ''programming'', ''language'']
Puntales a la respuesta usando
iter
.
Las respuestas acumuladas son mis favoritas.
Aquí hay otra respuesta acumulada utilizando un
map
lugar de una lista de comprensión.
import itertools
s = ''Pythonisanprogramminglanguage''
arr = [''lkjhgf'', ''zx'', ''qw'', ''ertyuiopakk'', ''foacdhlc'']
ticks = itertools.accumulate(map(len, arr[0:]))
words = list(map(lambda i, x: s[i:len(x) + i], (0,) + tuple(ticks), arr))
Salida:
[''Python'', ''is'', ''an'', ''programming'', ''language'']
Una forma mas
a,l = 0,[]
for i in map(len,arr):
l.append(s[a:a+i])
a+=i
print (l)
#[''Python'', ''is'', ''an'', ''programming'', ''language'']
Una forma sería hacer esto:
s = ''Pythonisanprogramminglanguage''
arr = [''lkjhgf'', ''zx'', ''qw'', ''ertyuiopakk'', ''foacdhlc'']
expected = []
i = 0
for word in arr:
expected.append(s[i:i+len(word)])
i+= len(word)
print(expected)
Usando un simple bucle for esto se puede hacer de la siguiente manera:
s = ''Pythonisanprogramminglanguage''
arr = [''lkjhgf'', ''zx'', ''qw'', ''ertyuiopakk'', ''foacdhlc'']
start_index = 0
expected = list()
for a in arr:
expected.append(s[start_index:start_index+len(a)])
start_index += len(a)
print(expected)