J'ai écrit un script qui lit les données de deux fichiers différents et procède en conséquence. Cependant, quand j'ai écrit le script, j'avais l'impression que le premier fichier à partir duquel je lis n'a que deux lignes, malheureusement cela a changé depuis.

Mon code extrait les deux premières lignes et transmet les données à une autre fonction, qui procède ensuite au calcul en passant par plusieurs autres fonctions.

En ce moment, je fais quelque chose comme ça:

try:
    file = open(myfile, 'r')
    for line in file:
        if line[0] != '|':
            name = line.strip('\n')
        else:
            data = line.strip('|\n')

Le fichier ressemble en général à ceci:

Samantha
|j&8ju820kahu9|

Maintenant, malheureusement, je peux avoir un fichier qui peut avoir plusieurs lignes, comme suit:

Andy
|o81kujd0-la88js|
Mathew
|a992kma82nf-x01j4|
Andrew
|01ks83nnz;a82jlad|

Existe-t-il un moyen d'extraire deux lignes à la fois d'un fichier? Traitez-les puis procédez à l'extraction de deux autres? Saisissez donc les deux premières lignes, donnez-leur à name + data, qui les transmet à ma fonction, imprimant éventuellement ce qui est requis, puis récupérez les deux nouvelles lignes et ainsi de suite.

Veuillez conseiller.

2
Nauman Shahid 17 avril 2018 à 22:45

5 réponses

Meilleure réponse

Oui, car le contexte du fichier est également un itérateur:

with open(filename, 'r') as f:
    for l1, l2 in zip(f, f):
        # ... do something with l1 and l2

C'est le chemin le plus court et le plus pythonique.

6
OneRaynyDay 17 avril 2018 à 19:56

Vous pouvez utiliser la notation d'épissage de liste list[<begin>:<end>:<step>] pour ignorer les éléments de liste lors de l'itération. Si votre fichier est petit, vous pouvez simplement le lire d'un coup en mémoire avec readlines()

Considérez quelque chose comme ça n'utilisez pas file comme descripteur de fichier. Il crée une ombre sur file

In [9]: a = my_file.readlines()
In [10]: for i, line in enumerate(a[::2]):
   ...:     data_line = a[i+1]
   ...:     name = line.strip('\n')
   ...:     data = data_line.strip("|\n")
   ...:     print name
   ...:     print data
   ...:
Andy
o81kujd0-la88js
Mathew
Mathew
Andrew
a992kma82nf-x01j4

In [11]:

(Je ferais personnellement quelque chose comme un match regex cependant).

-1
Srini 17 avril 2018 à 20:05

Une solution pour vous pourrait être:

data = {}
with open(filename) as f:
    for name, value in zip(f, f):
        data[name] = value

Pour une explication sur la fonction zip avec des itérateurs, consultez la documentation documentation.

En outre, cela provient de la recette de la documentation d'itertools:

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
TwistedSim 17 avril 2018 à 20:23

Bien sûr vous pouvez.

okay = False
with open(...) as f:
  while True:
    okay = False
    try:
      line_1 = next(f)
      line_2 = next(f)
      okay = True
      # ... do something with the pair of lines
    except StopIteration:
      break;  # End of file.
if not okay:
   complain("The file did not contain an even number of lines")
0
9000 17 avril 2018 à 20:07

Essaye ça

from itertools import islice
with open(filename, 'r') as infile:
    current_slice = islice(infile, N)
for line in current_slice:
    print line

N est le nombre de lignes que vous souhaitez traiter et current_slice est un objet générateur, qui vous donne chaque ligne du fichier et peut être utilisé dans une boucle. cela devrait vous donner deux lignes à la fois. au lieu d'imprimer, vous pouvez effectuer vos opérations, puis passer aux deux lignes suivantes

Une autre option est

from itertools import izip_longest

with open(filename) as f:
     for lines in grouper(f, N, ''):
         for line in lines:
             # process N lines here
-2
AbtPst 17 avril 2018 à 20:00