Tengo una cadena en python que tiene aproximadamente 3900 caracteres de largo . la cadena tiene múltiples caracteres, incluidas nuevas líneas muchas veces . Para simplificar, considere la siguiente cadena:

s = "this is a looooooooooooooooooooooooooong string which is \n split into \n a lot of \n new lines \n and I need to split \n it into roughly \n two halves on the new line\n"

Me gustaría dividir la cadena anterior en aproximadamente dos mitades en \ n para que el resultado esperado sea algo como esto:

first part = "this is a looooooooooooooooooooooooooong string which is \n split into \n a lot of "
second part = " new lines \n and I need to split \n it into roughly \n two halves on the new line\n"

Tengo este código de Python:

firstpart, secondpart = s[:len(s)/2], s[len(s)/2:]

Pero obviamente esto divide la cadena en la mitad exacta de cualquier carácter que esté en esa posición.

0
Scooby 22 feb. 2018 a las 20:59

4 respuestas

La mejor respuesta

¿Algo como esto?

mid = len(s)//2

try:
    break_at = mid + min(-s[mid::-1].index('\n'), s[mid:].index('\n'), key=abs)
except ValueError:  # if '\n' not in s
    break_at = len(s)

firstpart, secondpart = s[:break_at], s[break_at:]

secondpart comenzará con el carácter de nueva línea.

3
eugenhu 22 feb. 2018 a las 19:09

Prueba también esto.

split=s.splitlines()
half=int(len(split)/2)

first=''.join(split[half:])
second=''.join(split[:half])
0
Rayadurai 22 feb. 2018 a las 18:18

Aquí hay otra forma. Divida la cadena en '\n' y realice un seguimiento de 3 cosas:

  • El índice en la lista de cadenas divididas
  • La diferencia absoluta entre la posición de la subcadena actual y el medio de la cadena
  • La subcadena

Por ejemplo:

s_split = [(i, abs(len(s)//2 - s.find(x)), x) for i, x in enumerate(s.split('\n'))]
#[(0, 81, 'this is a looooooooooooooooooooooooooong string which is '),
# (1, 23, ' split into '),
# (2, 10, ' a lot of '),
# (3, 1, ' new lines '),
# (4, 13, ' and I need to split '),
# (5, 35, ' it into roughly '),
# (6, 53, ' two halves on the new line'),
# (7, 81, '')]

Ahora puede ordenar esta lista por el segundo elemento en la tupla para encontrar la subcadena más cercana al centro. Use este índice para construir sus cadenas uniéndose usando '\n':

idx_left = min(s_split, key=lambda x: x[1])[0]
first = "\n".join([s_split[i][2] for i in range(idx_left)])
second = "\n".join([s_split[i][2] for i in range(idx_left, len(s_split))])

print("%r"%first)
print("%r"%second)
#'this is a looooooooooooooooooooooooooong string which is \n split into \n a lot of '
#' new lines \n and I need to split \n it into roughly \n two halves on the new line\n'
2
pault 22 feb. 2018 a las 18:24

Prueba esto:

mid = len(s)/2
about_mid = mid + s[mid:].index('\n')

parts = s[:about_mid], s[about_mid+1:]
2
Arkady 22 feb. 2018 a las 18:11