Comment lire un fichier sans retour à la ligne?


374

En Python, appeler

temp = open(filename,'r').readlines()

résulte en une liste dans laquelle chaque élément est une ligne du fichier. C'est un peu stupide mais quand même: readlines()écrit également un caractère de nouvelle ligne dans chaque élément, ce que je ne souhaite pas.

Comment puis-je l'éviter?


4
Bande Utilisation: [l.strip('\n\r') for l in temp]. Ou même rstrip. Et depuis l'itération ici, cela peut être in openau lieu de in temp.
gorlum0

11
Je serais bien si en Python 3 il y avait une valeur pour définir l' newlineargument ouvert à ces nouvelles lignes traînantes.
jxramos

Réponses:


555

Vous pouvez lire le fichier entier et les lignes de séparation en utilisant str.splitlines:

temp = file.read().splitlines()

Ou vous pouvez dépouiller la nouvelle ligne à la main:

temp = [line[:-1] for line in file]

Remarque: cette dernière solution ne fonctionne que si le fichier se termine par une nouvelle ligne, sinon la dernière ligne perdra un caractère.

Cette hypothèse est vrai dans la plupart des cas ( en particulier pour les fichiers créés par les éditeurs de texte, qui souvent font ajouter une nouvelle ligne de fin de toute façon).

Si vous voulez éviter cela, vous pouvez ajouter une nouvelle ligne à la fin du fichier:

with open(the_file, 'r+') as f:
    f.seek(-1, 2)  # go at the end of the file
    if f.read(1) != '\n':
        # add missing newline if not already present
        f.write('\n')
        f.flush()
        f.seek(0)
    lines = [line[:-1] for line in f]

Ou une alternative plus simple est à stripla place de la nouvelle ligne:

[line.rstrip('\n') for line in file]

Ou même, bien qu'assez illisible:

[line[:-(line[-1] == '\n') or len(line)+1] for line in file]

Ce qui exploite le fait que la valeur de retour de orn'est pas un booléen, mais l'objet évalué comme vrai ou faux.


La readlinesméthode est en fait équivalente à:

def readlines(self):
    lines = []
    for line in iter(self.readline, ''):
        lines.append(line)
    return lines

# or equivalently

def readlines(self):
    lines = []
    while True:
        line = self.readline()
        if not line:
            break
        lines.append(line)
    return lines

Depuis, readline()la nouvelle ligne la readlines()conserve également .

Remarque: pour la symétrie de readlines()la writelines()méthode n'ajoute pas de fin de ligne, f2.writelines(f.readlines())produit donc une copie exacte de fin f2.


1
Notez que [line.rstrip('\n') for line in file]cela supprimera plus d'un suivi \n.
Wes Turner

1
Plus simplement, [line[:-(line[-1] == '\n') or len(line)+1] for line in file]pourrait plutôt l'être [line[:-(line[-1] == '\n') or None] for line in file].
Wes Turner

10
Ces solutions lisent l'intégralité du fichier en mémoire. Changer les crochets d'une compréhension de liste en parenthèses crée une expression de générateur qui vous permet d'itérer sur le fichier une ligne à la fois: for line in (x.strip() for x in f):
Joseph Sheedy

2
@velotron Ce n'est pas vraiment le but de la question / réponse. Aussi: gardez à l'esprit que withles fichiers sont fermés à la fin du bloc, ce qui signifie que vous ne pouvez pas faire with open(...) as f: lines = (line for line in f)et utiliser en linesdehors de withcar vous obtiendrez une erreur d'E / S. Vous pouvez être paresseux en utilisant un genexp, mais vous devez le consommer avant de fermer le fichier.
Bakuriu

@WesTurner. Mais il n'y aura pas plus d'un saut de ligne de fin. La nouvelle ligne supplémentaire fera partie de la prochaine ligne vide
Mad Physicist

38
temp = open(filename,'r').read().split('\n')

14
Que se passerait-il avec les \r\nnouvelles lignes? ;)
Wolph

26
Python gère automatiquement les sauts de ligne universels, donc .split('\n')se divise correctement, indépendamment de la convention de retour à la ligne. Il serait important que vous lisiez le fichier en mode binaire.Dans ce cas, il splitlines()gère les sauts de ligne universels alors que ce split('\n')n'est pas le cas.
Bakuriu

7
Et il y a toujours os.linesep:)
askewchan

1
@LarsH, cela aiderait dans certaines circonstances, sur les \r\nterminaisons de ligne de mon système ne sont pas converties en \n, qu'elles soient lues en texte ou en binaire, donc os.linesepfonctionnerait là où \ncela ne fonctionne pas. Mais splitlinesc'est clairement le meilleur choix, dans le cas où vous mentionnez où le fichier ne correspond pas au système d'exploitation. Vraiment, je l'ai surtout mentionné au cas où les gens qui regardaient cette discussion n'étaient pas au courant de son existence.
askewchan

1
@askewchan Vous utilisez peut-être une version obsolète de Python. Je crois qu'à partir de Python 3, les sauts de ligne universels sont activés par défaut, c'est \r\n-à- dire qu'ils seraient convertis pour les fichiers texte même lorsque vous utilisez Linux.
Arthur Tacca du

13

un autre exemple:

Lecture du fichier une ligne à la fois. Suppression des caractères indésirables à partir de la fin de la chaînestr.rstrip(chars)

with open(filename, 'r') as fileobj:
    for row in fileobj:
        print( row.rstrip('\n') )

voir aussi str.strip([chars])etstr.lstrip([chars])

(python> = 2.0)


10
temp = open(filename,'r').read().splitlines()

5
Êtes-vous sûr que cela ferme le fichier? Je pense que ce n'est pas le cas, donc ce n'est pas vraiment un
vol simple

9

Je pense que c'est la meilleure option.

temp = [line.strip() for line in file.readlines()]

8
Cette solution supprime également les espaces de début et de fin, ce qui n'est pas prévu.
Roland Illig

Mais la compréhension est vraiment sympa. Au moins avec Python 3, on peut utiliser temp = [line.rstrip() for line in file.readlines()]pour obtenir ce que les notes @Roland_Illig sont destinées.
bballdave025

Si vous allez parcourir toutes les lignes, pourquoi ne pas le faire paresseusement? Avec .readlines(), vous effectuez deux fois l'itération sur l'ensemble du fichier.
AMC

1

Essaye ça:

u=open("url.txt","r")  
url=u.read().replace('\n','')  
print(url)  

4
Bien que cet extrait de code puisse résoudre la question, y compris une explication aide vraiment à améliorer la qualité de votre message. N'oubliez pas que vous répondrez à la question pour les lecteurs à l'avenir, et ces personnes pourraient ne pas connaître les raisons de votre suggestion de code. Essayez également de ne pas surcharger votre code avec des commentaires explicatifs, car cela réduit la lisibilité du code et des explications!
Au revoir StackExchange

Je ne vois pas pourquoi quelqu'un devrait utiliser cela sur certaines des solutions alternatives.
AMC

-1
my_file = open("first_file.txt", "r")
for line in my_file.readlines():
    if line[-1:] == "\n":
        print(line[:-1])
    else:
        print(line)
my_file.close() 

3
Veuillez ajouter quelques explications afin qu'elles soient utiles aux autres.
samuellawrentz

Vous devez utiliser un gestionnaire de contexte pour gérer l'objet fichier et parcourir directement le fichier. En utilisant .readlines()comme ceci, vous parcourez efficacement le fichier entier deux fois.
AMC

-2
import csv

with open(filename) as f:
    csvreader = csv.reader(f)
    for line in csvreader:
         print(line[0])

2
Mais que faire si la ligne contient une virgule?
gilch

-8
def getText():
    file=open("ex1.txt","r");

    names=file.read().split("\n");
    for x,word in enumerate(names):
        if(len(word)>=20):
            return 0;
            print "length of ",word,"is over 20"
            break;
        if(x==20):
            return 0;
            break;
    else:
        return names;


def show(names):
    for word in names:
        len_set=len(set(word))
        print word," ",len_set


for i in range(1):

    names=getText();
    if(names!=0):
        show(names);
    else:
        break;
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.