Як прочитати файл без нових рядків?


374

У Python дзвонять

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

приводить до списку, в якому кожен елемент є рядком у файлі. Це трохи нерозумно, але все-таки: readlines()також записую символ нового рядка до кожного елемента, чогось я не хочу робити.

Як я можу цього уникнути?


4
Використання смуги: [l.strip('\n\r') for l in temp]. Або навіть rstrip. А оскільки ітерація тут може бути in openзамість in temp.
gorlum0

11
Мені було б добре, якби в Python 3 знайшлося значення для встановлення newlineаргументу open на ті чіткі нові рядки.
jxramos

Відповіді:


554

Ви можете прочитати весь файл та розділити рядки, використовуючи str.splitlines:

temp = file.read().splitlines()

Або ви можете зняти нову лінію вручну:

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

Примітка: останнє рішення працює лише в тому випадку, якщо файл закінчується новим рядком, інакше останній рядок втратить символ.

Це припущення справедливо у більшості випадків (особливо для файлів, створених текстовими редакторами, які часто так чи інакше додають закінчуючий рядок).

Якщо ви хочете цього уникнути, ви можете додати новий рядок у кінці файлу:

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]

Або ж більш простою альтернативою є stripновий рядок:

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

Або навіть, хоча досить нечитабельно:

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

Що використовує той факт, що повернене значення orне булеве, а об'єкт, який оцінювався як істинне чи помилкове.


readlinesМетод фактично еквівалентно:

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

Оскільки readline()зберігає новий рядок, він також readlines()зберігає його.

Примітка: для симетрії до readlines()в writelines()методі зовсім НЕ додавати закінчення перекладу рядка, тому f2.writelines(f.readlines())виробляє точну копію fв f2.


1
Зверніть увагу, що [line.rstrip('\n') for line in file]буде видалено більше одного останнього \n.
Уес Тернер

1
Простіше кажучи, [line[:-(line[-1] == '\n') or len(line)+1] for line in file]міг бути натомість [line[:-(line[-1] == '\n') or None] for line in file].
Уес Тернер

10
Ці рішення читають весь файл в пам'яті. Зміна квадратних дужок розуміння списку на дужки створює генераторне вираження, яке дозволяє вам повторювати файл по одному рядку за раз: for line in (x.strip() for x in f):
Джозеф Шеді

2
@velotron Це не справді суть питання / відповіді. Крім того: пам’ятайте, що withзакриває файли, коли блок припиняється, а це означає, що ви не можете робити with open(...) as f: lines = (line for line in f)та використовувати linesпоза, withоскільки ви отримаєте помилку вводу / виводу. Ви можете лінуватися, використовуючи genexp, але потрібно споживати його перед тим, як закрити файл.
Бакуріу

@WesTurner. Але не буде більше одного зворотного рядка. Додатковий новий рядок буде частиною наступного порожнього рядка
Божевільний фізик

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

14
Що буде з \r\nновими рядками? ;)
Вольф

26
Python автоматично обробляє універсальні нові рядки, таким чином, .split('\n')буде розділений правильно, незалежно від конвенції newline. Було б важливо, якщо ви читаєте файл у двійковому режимі. У цьому випадку splitlines()обробляються універсальні нові рядки, поки split('\n')немає.
Бакуріу

7
І завжди є os.linesep:)
askewchan

1
@LarsH, це допомогло б за деяких обставин, у моєму системному \r\nрядку закінчення не перетворюються на те \n, чи читаються вони як текстові чи двійкові, тому вони os.linesepбудуть працювати там, де \nцього немає. Але splitlines, безумовно, кращий вибір, якщо ви згадуєте, де файл не відповідає os. Дійсно, я згадав про це, якщо люди, які дивляться на цю дискусію, не знають про її існування.
askewchan

1
@askewchan Можливо, ви використовуєте застарілу версію Python. Я вважаю, що, як і в Python 3, універсальні нові рядки включені за замовчуванням, тобто \r\nбудуть перетворені для текстових файлів, навіть коли ви працюєте в Linux.
Артур Такка

13

ще один приклад:

Читання файлів одночасно. Видалення непотрібних символів з кінця рядкаstr.rstrip(chars)

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

див. також str.strip([chars])іstr.lstrip([chars])

(python> = 2.0)



9

Я думаю, що це найкращий варіант.

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

8
Це рішення також видаляє провідні та кінцеві простори, що не призначено.
Роланд

Хоча розуміння справді приємне. Принаймні, з Python 3, ви можете використовувати, temp = [line.rstrip() for line in file.readlines()]щоб отримати те, що @Roland_Illig зазначає, що призначено.
bballdave025

Якщо ви збираєтесь переглядати всі лінії, чому б не так ліниво? З .readlines(), ви ефективно повторюєте весь файл двічі.
AMC

1

Спробуйте це:

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

4
Хоча цей фрагмент коду може вирішити питання, зокрема пояснення дійсно допомагає покращити якість вашої публікації. Пам’ятайте, що ви відповідаєте на запитання читачів у майбутньому, і ці люди можуть не знати причини вашої пропозиції щодо коду. Будь ласка, намагайтеся не переповнювати свій код пояснювальними коментарями, оскільки це зменшує читабельність і коду, і пояснень!
Goodbye StackExchange

Я не бачу, чому хтось повинен використовувати це над деякими альтернативними рішеннями.
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
Будь ласка, додайте пояснення, щоб воно було корисним іншим.
samuellawrentz

Ви повинні використовувати диспетчер контексту для обробки файлового об'єкта та ітерації над файлом безпосередньо. Використовуючи .readlines()подібне, ви ефективно повторюєте над усім файлом двічі.
AMC

-2
import csv

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

2
Але що робити, якщо у рядку є кома?
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;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.