Tengo una cadena multilínea en Python que se ve así
"""1234 dog list some words 1432 cat line 2 1789 cat line3 1348 dog line 4 1678 dog line 5 1733 fish line 6 1093 cat more words"""
Quiero poder agrupar líneas específicas por los animales en python. Entonces mi salida se vería así
dog
1234 dog list some words
1348 dog line 4
1678 dog line 5
cat
1432 cat line 2
1789 cat line3
1093 cat more words
fish
1733 fish line 6
Hasta ahora sé que necesito dividir el texto por cada línea
def parser(txt):
for line in txt.splitlines():
print(line)
Pero no estoy seguro de cómo continuar. ¿Cómo agruparía cada línea con un animal?
3 respuestas
Puede utilizar defaultdict y dividir cada línea:
from collections import defaultdict
txt = """123 dog foo
456 cat bar
1234 dog list some words
1348 dog line 4
1432 cat line 2
1789 cat line3
1093 cat more words
1678 dog line 5
"""
def parser(txt):
result = defaultdict(list)
for line in txt.splitlines():
num, animal, _ = line.split(' ', 2) # split the first 2 blancs, skip the rest!
result[animal].append(line) # add animal and the whole line into result
return result
result = parser(txt)
for animal, lines in result.items():
print('>>> %s' % animal)
for line in lines:
print(line)
print("")
Salida:
>>> dog
123 dog foo
1234 dog list some words
1348 dog line 4
1678 dog line 5
>>> cat
456 cat bar
1432 cat line 2
1789 cat line3
1093 cat more words
str1 = """1234 dog list some words 1432 cat line 2 1789 cat line3 1348 dog line 4 1678 dog line 5 1733 fish line 6 1093 cat more words"""
animals = ["dog", "cat", "fish"]
tmp = {}
tmp1= []
currentAnimal = ""
listOfWords = str1.split(" ")
for index, line in enumerate(listOfWords, start=1):
if line in animals:
currentAnimal = line
if len(tmp1)>0:
tmp1.pop()
if currentAnimal not in tmp.keys():
tmp[currentAnimal] = []
tmp[currentAnimal].append(tmp1)
tmp1=[]
tmp1 = []
tmp1.append(listOfWords[index-2])
tmp1.append(listOfWords[index-1])
else:
tmp1.append(listOfWords[index-1])
for eachKey in tmp:
print eachKey
listOfStrings = tmp[eachKey]
for eachItem in listOfStrings:
if len(eachItem) > 0:
print (" ").join(eachItem)
Salida:
fish
1678 dog line 5
dog
1789 cat line3
1348 dog line 4
cat
1234 dog list some words
1432 cat line 2
1733 fish line 6
Sé que hay otras respuestas, pero me gusta más la mía (jajaja).
De todos modos, analicé la cadena original como si la cadena no tuviera caracteres \n
(nueva línea).
Para obtener los animales y las oraciones, utilicé expresiones regulares:
import re
# original string with no new line characters
txt = """1234 dog list some words 1432 cat line 2 1789 cat line3 1348 dog line 4 1678 dog line 5 1733 fish line 6 1093 cat more words"""
# use findall to capture the groups
groups = re.findall("(?=(\d{4} (\w+) .*?(?=\d{4}|$)))", txt)
En este punto, obtengo una lista de tuplas en groups
:
>>> groups
[('1234 dog list some words ', 'dog'),
('1432 cat line 2 ', 'cat'),
('1789 cat line3 ', 'cat'),
('1348 dog line 4 ', 'dog'),
('1678 dog line 5 ', 'dog'),
('1733 fish line 6 ', 'fish'),
('1093 cat more words', 'cat')]
Luego me gustaría agrupar todas las oraciones que se refieren al mismo animal. Es por eso que creé una estructura de datos llamada tabla hash (también conocido como diccionario, en Python):
# create a dictionary to store the formatted data
dct = {}
for group in groups:
if group[1] in dct:
dct[group[1]].append(group[0])
else:
dct[group[1]] = [group[0]]
El diccionario dct
tiene este aspecto:
>>> dct
{'dog': ['1234 dog list some words ', '1348 dog line 4 ', '1678 dog line 5 '],
'cat': ['1432 cat line 2 ', '1789 cat line3 ', '1093 cat more words'],
'fish': ['1733 fish line 6 ']}
Finalmente, solo tenemos que imprimirlo en el formato que desee:
# then print the result in the format you like
for key, value in dct.items():
print(key)
for sentence in value:
print(sentence)
print()
Y la salida es:
dog
1234 dog list some words
1348 dog line 4
1678 dog line 5
cat
1432 cat line 2
1789 cat line3
1093 cat more words
fish
1733 fish line 6
El código final es el siguiente:
import re
# original string with no new line characters
txt = """1234 dog list some words 1432 cat line 2 1789 cat line3 1348 dog line 4 1678 dog line 5 1733 fish line 6 1093 cat more words"""
# use findall to capture the groups
groups = re.findall("(?=(\d{4} (\w+) .*?(?=\d{4}|$)))", txt)
# create a dictionary to store the formatted data
dct = {}
for group in groups:
if group[1] in dct:
dct[group[1]].append(group[0])
else:
dct[group[1]] = [group[0]]
# then print the result in the format you like
for key, value in dct.items():
print(key)
for sentence in value:
print(sentence)
print()
Preguntas relacionadas
Preguntas vinculadas
Nuevas preguntas
python
Python es un lenguaje de programación multipropósito, de tipificación dinámica y de múltiples paradigmas. Está diseñado para ser rápido de aprender, comprender y usar, y hacer cumplir una sintaxis limpia y uniforme. Tenga en cuenta que Python 2 está oficialmente fuera de soporte a partir del 01-01-2020. Aún así, para preguntas de Python específicas de la versión, agregue la etiqueta [python-2.7] o [python-3.x]. Cuando utilice una variante de Python (por ejemplo, Jython, PyPy) o una biblioteca (por ejemplo, Pandas y NumPy), inclúyala en las etiquetas.