Lire un fichier dans l'ordre inverse à l'aide de python
Comment lire un fichier dans l'ordre inverse à l'aide de python? Je veux lire un fichier à partir de la dernière ligne à la première ligne.
- Voulez-vous dire "à lire dans l'ordre inverse" ou "processus les lignes dans l'ordre inverse"? Il y a une différence. Avec la première, potentiellement le fichier ne s'inscrirait pas dans la mémoire de tous en même temps, si vous voulez traiter les lignes dans l'ordre inverse, mais vous ne pouvez pas lire l'intégralité du fichier et l'inverser. Avec le second, vous pourriez lire l'intégralité du fichier, et d'inverser la liste des lignes avant de les traiter. Alors, qui est-il?
- Voir aussi: Obtenir les n dernières lignes d'un fichier avec Python, semblable à la queue
- Je recommande ce-pas de problèmes de mémoire et rapide: stackoverflow.com/a/260433/1212562
Vous devez vous connecter pour publier un commentaire.
Et en Python 3:
with
instruction est généralement tout à fait indolore.Une bonne, réponse efficace à l'écrit comme un générateur.
fh.seek(0, os.SEEK_END)
et la modification de lafh.seek(-offset, os.SEEK_END)
tropfh.seek(file_size - offset)
.fh.seek()
retourneNone
utf8
),seek()
etread()
se référer à différentes tailles. C'est probablement aussi la raison pour laquelle les non-zéro premier argument deseek()
par rapport àos.SEEK_END
n'est pas pris en charge.'aöaö'.encode()
estb'a\xc3\xb6a\xc3\xb6'
. Si vous pouvez l'enregistrer sur le disque puis de les lire en mode texte, lorsque vous neseek(2)
il va se déplacer par deux octets, de sorte queseek(2); read(1)
entraînera une erreur deUnicodeDecodeError: 'utf-8' codec can't decode byte 0xb6 in position 0: invalid start byte
, mais si vous neseek(0); read(2); read(1)
, vous obtiendrez la'a'
que vous attendiez, c'est:seek()
n'est jamais encodage de la conscience,read()
est si vous ouvrez le fichier en mode texte. Maintenant, si vous avez'aöaö' * 1000000
, vos blocs ne seront pas alignés correctement.flyingcircus.util.readline(reverse=True)
). Avertissement: je suis l'auteur du paquet.Comment quelque chose comme cela:
Depuis le fichier est en lecture caractère par caractère dans l'ordre inverse, il fonctionnera même sur de très gros fichiers, tant que les lignes individuelles tenir en mémoire.
Vous pouvez également utiliser le module python
file_read_backwards
.Après l'installation, via
pip install file_read_backwards
(v1.2.1), vous pouvez lire l'intégralité du fichier vers l'arrière (en ligne-sage), dans une mémoire de manière efficace par le biais de:Il prend en charge "utf-8","latin-1", et "ascii" encodages.
Est également disponible pour python3. La documentation complémentaire peut être trouvé à http://file-read-backwards.readthedocs.io/en/latest/readme.html
Si vous êtes sous linux, vous pouvez utiliser
tac
commande.2 recettes que vous pouvez trouver dans ActiveState ici et ici
__reversed__()
méthode est nécessaire, mais python2.5 ne pas se plaindre d'une classe personnalisée sans elle.__reversed__
méthode est également pas nécessaire, et il n'a pas une telle chose. Si un objet permet d'__len__
et__getitem__
il fonctionne très bien (moins quelques cas exceptionnels, comme dict).__reversed__
?__len__
et__getitem__
, il fonctionne exactement comme décrit (par exemple: codepad.org/aglIbcXy ). Listes de travail comme décrit (voir la définition de list_reverse (__reversed__
) à svn.python.org/view/python/trunk/Objects/... ).reversed()
est appelé sur elle, parce que c'est ce que readlines() n'. il ne construit pas la liste dans l'ordre inverse, c'est plutôt elle crée un itérateur qui itère sur la liste (dans l'ordre), vers l'arrière.__reversed__()
ce serait cool. En fait, les deux réponses à l'aide dereadlines()
sont horriblement inefficace pour les gros fichiers.for line in open("file")
Ici vous pouvez trouver mon application, vous pouvez limiter l'utilisation de la ram en changeant le "tampon" de la variable, il y a un bug que le programme affiche une ligne vide au début.
Et aussi l'utilisation de la ram peut être augmenter si il n'y a pas de nouvelles lignes pour plus d'octets de la mémoire tampon, "fuite" variable augmente jusqu'à voir une nouvelle ligne ("\n").
C'est aussi en travaillant pour 16 GO de fichiers qui est plus grande que ma mémoire totale.
Merci pour la réponse @srohde. Il a un petit bug vérification de caractère de saut de ligne avec " est " de l'opérateur, et je ne pouvais pas commenter la réponse avec 1 réputation. Je tiens aussi à gérer un fichier ouvert à l'extérieur, car cela me permet d'intégrer mes divagations pour luigi tâches.
Ce que j'avais besoin de changer est de la forme:
J'aimerais changer pour:
Ici est une modification de la réponse qui se veut un descripteur de fichier et de garde des retours à la ligne:
une fonction simple pour créer un deuxième fichier inversé (linux uniquement):
comment utiliser
mv mycontent.txt $'hello $(rm -rf $HOME) world.txt'
, ou même en utilisant un nom de fichier de sortie donnée par un utilisateur non fiable? Si vous souhaitez gérer l'arbitraire des noms de fichiers en toute sécurité, il faut plus de prudence.subprocess.Popen(['tac', file1], stdout=open(file2, 'w'))
serait à l'abri, par exemple.Accepté de répondre ne fonctionne pas pour les cas avec de gros fichiers qui ne tiennent pas en mémoire (ce qui n'est pas un cas rare).
Comme il a été noté par les autres, @srohde répondre semble bon, mais il a prochaines questions:
même si nous refactoriser à accepter de fichier de l'objet, il ne fonctionnera pas pour tous les encodages: on peut choisir fichier avec
utf-8
d'encodage et de non-ascii contenu commepasser
buf_size
égal à1
et aurabien sûr, le texte peut être plus grande, mais
buf_size
peut être ramassé, donc il va conduire à d'obfuscation d'erreur comme ci-dessus,Si l'on considère l'ensemble de ces préoccupations que j'ai écrit des fonctions distinctes:
Tout d'abord nous allons définir ensuite les fonctions de l'utilitaire:
ceil_division
pour la fabrication de division avec le plafond (en contraste avec la norme//
division avec le plancher, plus d'informations peuvent être trouvées dans ce fil)split
pour le fractionnement de la chaîne par le séparateur d'extrémité droite avec la possibilité de le garder:read_batch_from_end
pour le lot de lecture à partir de l'extrémité droite de flux binaireAprès cela, nous pouvons définir la fonction de lecture de flux d'octets dans l'ordre inverse comme
et enfin une fonction d'inversion de fichier texte peut être défini comme:
Tests
Préparations
J'ai généré 4 fichiers à l'aide de
fsutil
commande:aussi j'ai refait @srohde solution pour travailler avec des fichiers objet au lieu de le chemin d'accès au fichier.
Script de Test
Note: j'ai utilisé
collections.deque
classe d'échappement de la génératrice.Sorties
Pour PyPy 3.5 sur Windows 10:
Pour Disponible 3.5 sur Windows 10:
Ainsi, comme nous pouvons le voir se comporte comme solution originale, mais elle est plus générale et sans ses inconvénients énumérés ci-dessus.
Annonce
J'ai ajouté ceci à
0.3.0
version delz
le paquet (nécessite Python 3.5+) qui ont bien testé fonctionnel/itération utilitaires.Peut être utilisé comme
Il prend en charge tous les encodages standard (peut-être à l'exception de
utf-7
car il est difficile pour moi de définir une stratégie pour générer des chaînes de encodable avec elle).Si vous êtes inquiet au sujet de la taille du fichier /utilisation de la mémoire, de la mémoire-la cartographie du fichier et la numérisation vers l'arrière pour les retours à la ligne est une solution:
Comment rechercher une chaîne de caractères dans des fichiers texte?
avec open("filename") comme f:
Toujours utiliser
with
lorsque vous travaillez avec des fichiers comme il s'occupe de tout pour vous:Ou en Python 3:
vous devez d'abord ouvrir votre fichier en lecture format, l'enregistrer dans une variable, puis ouvrez le deuxième fichier au format écrit où vous pouvez écrire ou ajouter la variable à l'aide d'un l' [::-1] tranche, renversant complètement le fichier. Vous pouvez également utiliser readlines() pour faire une liste de lignes, vous pouvez manipuler
La plupart des réponses ont besoin de lire le fichier en entier avant de faire quoi que ce soit. Cet exemple lit de plus en plus de grands échantillons à partir de la fin.
Je n'ai vu Murat Yükselen de réponse lors de l'écriture de cette réponse. C'est presque le même, qui, je suppose, est une bonne chose. L'exemple ci-dessous traite aussi avec \r et augmente sa taille de tampon à chaque étape. J'ai aussi quelques les tests unitaires pour ce code.
Lire le fichier ligne par ligne, puis de l'ajouter sur une liste dans l'ordre inverse.
Voici un exemple de code :
à utiliser:
J'ai dû le faire il y a quelques temps et utilisé le code ci-dessous. Il des tuyaux pour le shell. Je crains de ne pas avoir le script complet plus. Si vous êtes sur un unixish système d'exploitation, vous pouvez utiliser "tac", mais, par exemple, Mac OSX tac commande ne fonctionne pas, l'utilisation de la queue -r. Ci-dessous l'extrait de code de tests pour la plate-forme sur laquelle vous êtes, et ajuste la commande en conséquence