4
votes

Comment diviser toutes les 2 lignes en Python?

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?


0 commentaires

7 Réponses :


0
votes

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)


0 commentaires

1
votes

Vous pouvez diviser sur \n , puis regrouper les éléments deux par deux:

Peut-être comme ça:

['subject \n property', 'subject \n property']

production:

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


1 commentaires

Correct, comme mentionné dans le commentaire: # you will have to ensure the number of elements is even, or protect against an Indexerror



1
votes

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)


0 commentaires

0
votes
s = "subject \nproperty \n subject \nproperty \n etc"
print(s.split(" \n "))
#['subject \nproperty', 'subject \nproperty', 'etc']

0 commentaires

0
votes

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 :)


0 commentaires

0
votes

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(",")


0 commentaires

1
votes

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


0 commentaires