J'ai une entrée qui a des propriétés réparties sur des lignes, mais chaque sujet a une nouvelle ligne avec une propriété. Donc mon entrée est:
"subject \n property \n subject \n property \n etc"
Je veux séparer cette entrée dans une liste de ["propriété subject \ n", "propriété \ n sujet", etc], cependant je suis plutôt nouveau dans python et il ne semble pas que je sois capable d'utiliser les .splitlines() pour chaque autre nouvelle ligne.
Est-ce que quelqu'un sait s'il existe un moyen de le faire avec .splitlines() ou existe-t-il une alternative plus simple?
7 Réponses :
Une façon dont je peux penser est de tout diviser, puis de le recoudre 2 à la fois, il peut y avoir un meilleur moyen
['subject \n property ', ' subject \n property ', ' etc']
my_str = "subject \n property \n subject \n property \n etc"
all_splits = my_str.split('\n')
ret = []
for i in range(0,len(all_splits),2):
ret.append(all_splits[i])
try:ret[-1]+="\n"+all_splits[i+1]
except: pass
print(ret)
Vous pouvez diviser sur \n , puis regrouper les éléments deux par deux:
Peut-être comme ça:
['subject \n property', 'subject \n property']
s = "subject \n property \n subject \n property \n"
s = s.split()
res = []
for idx in range(0, len(s), 2):
res.append(f'{s[idx]} \n {s[idx+1]}') # you will have to ensure the number of elements is even, or protect against an Indexerror
res
Correct, comme mentionné dans le commentaire: # you will have to ensure the number of elements is even, or protect against an Indexerror
Inspiré d'itertools:
s = text.split('\n')
res = [ '\n'.join(s[i:i+2]) for i in range(0, len(s) // 2, 2) ]
https://docs.python.org/3.10/library/itertools.html
donc :
from itertools import zip_longest
s = [text.split('\n')] * n # here n = 2
result = [ '\n'.join(lines).strip() for (*lines,) in zip_longest(*s, fill_value='') ]
(l'idée est en faisant: [text.split('\n')] * n , vous créez une liste contenant n fois le même itérateur. En utilisant zip_longest, vous groupez en utilisant cet itérateur n fois aussi, puis vous obtenez un tuple de n lignes à chaque itération. Ces lignes se suivent depuis que zip_longest appelle le suivant sur le même itérateur. Le dernier strip () gère le cas n_lines % n != 0 Une manière plus élégante mais un peu plus longue de gérer les dernières lignes serait : result = [ '\n'.join(l for l in lines if l is not None).strip() for (*lines,) in zip_longest(*s) ] )
Une autre manière plus simple à lire:
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 zip_longest(*args, fillvalue=fillvalue)
s = "subject \nproperty \n subject \nproperty \n etc"
print(s.split(" \n "))
#['subject \nproperty', 'subject \nproperty', 'etc']
Je vous suggère de diviser la chaîne par chaque ligne en utilisant la fonction splitlines () et à partir de la liste obtenue, de parcourir chaque index pair, de l'ajouter à une chaîne vide, puis d'ajouter l'index qui suit à la chaîne vide après une nouvelle ligne .
Jetez un œil à ce code:
def your_function(string): #Takes the combined string as input
list1 = string.splitlines()
list_to_return = []
for x in list1:
if list1.index(x) % 2 == 0:
list_to_return.append(f'{x} \n {list1[list1.index(x) + 1]}')
return list_to_return
Je crois que ce code fait ce que vous vouliez. Ne vous y trompez pas, ce n'est en aucun cas le moyen le plus simple ou le plus efficace de le faire. Mais cela fait le travail :)
Utiliser re.sub ferait. Supprimez les nouvelles lignes et espaces ('\ n \ s') et ajoutez une virgule après 'propriété', qui peut servir de séparateur dans la split :
['subject property', 'subject property', ' ']
La sortie est:
my_str = "subject \n property \n subject \n property"
my_str2 = re.sub('\n\s', '', my_str)
my_str3 = re.sub('property', 'property, ', my_str2)
my_str4 = re.sub(' subject', 'subject', my_str3)
my_str4.split(",")
Un peu de solution de style fonctionnel où vous pouvez compresser des tranches de liste
>>> text = "subject1\nproperty1\nsubject2\nproperty2"
>>> lines = text.splitlines()
>>> pairs = zip(lines[0::2], lines[1::2])
>>> list(pairs)
[('subject1', 'property1'), ('subject2', 'property2')]
>>> list(map("\n".join, pairs))
['subject1\nproperty1', 'subject2\nproperty2']