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']