Як видалити \ n з елемента списку?


79

Я намагаюся отримати Python до рядка для читання з файлу .txt і записати елементи першого рядка в список. Елементи у файлі були розділені табуляцією, тому я звик split("\t")розділяти елементи. Оскільки файл .txt має багато елементів, я зберігав дані, знайдені в кожному рядку, в окремий список.

Проблема, яку я маю на даний момент, полягає в тому, що він показує кожен список таким чином:

['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n']

Як я можу вилучити \nз останнього елемента списку і зробити його просто '7.3'?


З даними, які у вас є, просто використовуйте split () (без аргументів). Спочатку буде видалено пробіли, а потім розділено на пробіли.
JoshD

Відповіді:


147

Якщо ви хочете видалити лише \nз останнього елемента, використовуйте це:

t[-1] = t[-1].strip()

Якщо ви хочете видалити \nз усіх елементів, використовуйте це:

t = map(lambda s: s.strip(), t)

Ви також можете розглянути можливість видалення \n перед розбиттям рядка:

line = line.strip()
# split line...

6
Я б зробив смужку до розколу ... я відчуваю її більш стислою.
st0le

2
Хуцца! Це працює! Дуже дякую.
Mr Wotan

8
якби я збирався переглядати список, я б також використовував [s.strip() for s in t]. Я приурочив його, і це 5,33 мсек для обробки ["s\n"]*10000проти 9,73 мсек для map. mapвиграє, якщо це відображення вбудованого.
aaronasterling

3
line = line.strip()видалить ВСІ ПРИКЛЮЧНІ ПРОБЛЕМИ. Це бійня. Прочитайте відповідь Джима Денніса.
Джон Махін,

1
@ Джон Правда. Мало того, він також видалить усі провідні пробіли. За багатьох обставин це line.strip()було б більш розумно, ніж, line.rstrip('\n')і тому я написав це без додаткових пояснень. Однак у цьому випадку (значення, розділені табуляцією) ви на 100% праві: дійсно слід бути обережним з видаленням пробілів, що ведуть і завершують, оскільки порожній перший або останній стовпець може "зникнути".
Боло,

51

Починаючи з Python3

map більше не повертає a list але a mapObject, таким чином відповідь буде виглядати приблизно так

>>> map(lambda x:x.strip(),l)
<map object at 0x7f00b1839fd0>

Ви можете прочитати більше про це на Що нового в Python 3.0 .

map()і filter()повернути ітератори. Якщо вам справді потрібнаlist , це швидке виправлення, наприкладlist(map(...))

Тож які шляхи пройти через це?


Випадок 1 - listдзвінок закінченийmap допомогою alambda

mapповертає ітератор . list- це функція, яка може перетворити ітератор у список. Отже, вам потрібно буде обговорити listдзвінок map. Отже, відповідь тепер стає:

>>> l = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n']
>>> list(map(lambda x:x.strip(),l))
['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3']

Дуже добре, ми отримуємо результат. Тепер ми перевіряємо, скільки часу потрібно для виконання цього фрагмента коду.

$ python3 -m timeit "l = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n'];list(map(lambda x:x.strip(),l))"
100000 loops, best of 3: 2.22 usec per loop

2,22 мікросекунди. Це не так погано. Але чи є більш ефективні способи?


Випадок 2 - listдзвінок закінчено mapбез OUT alambda

lambdaбагато людей із спільноти Python (у тому числі Гвідо ) не бачать . Крім того, це значно зменшить швидкість програми. Отже, нам потрібно якомога більше уникати цього. Функція верхнього рівняstr.strip . Тут нам допомагають.

mapМоже бути переписано без використання lambdaвикористання в str.stripякості

>>> list(map(str.strip,l))
['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3']

А тепер про час.

$ python3 -m timeit "l = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n'];list(map(str.strip,l))"
1000000 loops, best of 3: 1.38 usec per loop

Фантастично. Ви можете побачити різницю в ефективності між двома способами. Це майже на 60% швидше. Таким чином, підхід без використання a lambdaтут кращий вибір.


Випадок 3 - Дотримання вказівок, регулярний спосіб

Ще одним важливим моментом у " Що нового в Python 3.0" є те, що він радить нам уникатиmap де це можливо.

Особливо хитро map()називають побічні ефекти функції; правильним перетворенням є використання регулярногоfor циклу (оскільки створення списку було б просто марним).

Тож ми можемо вирішити цю проблему без mapвикористання звичайного forциклу.

Банальним способом вирішення (груба сила) буде:

>>> l = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n']
>>> final_list = []
>>> for i in l:
...     final_list.append(i.strip())
... 
>>> final_list
['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3']

Налаштування часу

def f():
    l = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n']
    final_list = []
    for i in l:
         final_list.append(i.strip())
import timeit
print(min(timeit.repeat("f()","from __main__ import f")))

І результат.

1.5322505849981098

Як бачите, груба сила тут трохи повільніша. Але це, безумовно, легше для читання звичайним програмістом, ніж mapпункт.


Випадок 4 - розуміння списку

Список розуміння тут також можливо і таке ж , як і в python2.

>>> [i.strip() for i in l]
['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3']

Тепер щодо термінів:

$ python3 -m timeit "l = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n'];[i.strip() for i in l]"
1000000 loops, best of 3: 1.28 usec per loop

Як бачите, розуміння списку є більш ефективним, ніж map(навіть без а lambda). Звідси правило великого пальця в Python3 полягає у використанні розуміння списку замістьmap


Випадок 5 - Механізми на місці та космічна ефективність ( TMT )

Останній спосіб - це внести зміни до місця в самому списку. Це заощадить багато місця в пам'яті. Це можна зробити за допомогою enumerate.

>>> l = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n']
>>> for i,s in enumerate(l):
...     l[i] = s.strip()
... 
>>> l
['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3']

Результат часу буде 1.4806894720022683. Але однак цей спосіб є космічно ефективним.


Висновок

Порівняльний список часу (як Python 3.4.3, так і Python 3.5.0)

----------------------------------------------------
|Case| method          | Py3.4 |Place| Py3.5 |Place|
|----|-----------------|-------|-----|-------|-----|
| 1  | map with lambda | 2.22u | 5   | 2.85u | 5   |
| 2  | map w/o lambda  | 1.38u | 2   | 2.00u | 2   |
| 3  | brute-force     | 1.53u | 4   | 2.22u | 4   |
| 4  | list comp       | 1.28u | 1   | 1.25u | 1   |
| 5  | in-place        | 1.48u | 3   | 2.14u | 3   |
----------------------------------------------------

Наостанок зауважте, що розуміння списку - найкращий спосіб, а mapвикористання lambda- найгірший. Але знову --- ТІЛЬКИ В ПІФОНІ3


11

Здається, ви хочете щось на зразок Perl chomp() .

Це тривіально робити в Python:

def chomp(s):
    return s[:-1] if s.endswith('\n') else s

... припускаючи, що ви використовуєте Python 2.6 або пізнішої версії. В іншому випадку просто використовуйте трохи більш багатослівний:

def chomp(s):
    if s.endwith('\n'):
        return s[:-1]
    else:
        return s

Якщо ви хочете видалити всі нові рядки з кінця рядка (у непарному випадку, коли з якихось причин у одного може бути кілька нових рядків):

def chomps(s):
    return s.rstrip('\n')

Очевидно, що ви ніколи не повинні бачити такий рядок, який повертає будь-який звичайний об'єкт файлу Python readline() або readlines()методи.

Я бачив, як люди наосліп видаляють останні символи (використовуючи s[:-1] нарізки) з результатів файлуreadline() та подібних функцій. Це погана ідея, оскільки це може призвести до помилки в останньому рядку файлу (у випадку, коли файл закінчується чимось іншим, крім нового рядка).

Спочатку вас може заколисувати фальшиве почуття безпеки, коли наосліп зачищаєте кінцеві символи з прочитаних вами рядків. Якщо для створення файлів тестового набору ви використовуєте звичайний текстовий редактор, більшість із них буде мовчки додавати новий рядок до кінця останнього рядка. Щоб створити дійсний тестовий файл, використовуйте такий код:

f = open('sometest.txt', 'w')
f.write('some text')
f.close()

... а потім, якщо ви знову відкриєте цей файл і скористаєтесь readline()абоreadlines() застосуєте на ньому методи ви виявите, що текст читається без завершального нового рядка.

Ця невміння враховувати текстові файли, що закінчуються символами, що не мають нового рядка, страждає від багатьох службових програм UNIX та мов сценаріїв протягом багатьох років. Це дурна кутова базова помилка, яка закрадається в код досить часто, щоб бути шкідником, але недостатньо часто, щоб люди могли навчитися у нього. Ми можемо стверджувати, що "текстові" файли без остаточного нового рядка є "пошкодженими" або нестандартними; і це може бути дійсним для деяких специфікацій програмування.

Однак занадто легко ігнорувати кутові випадки в нашому кодуванні і змусити це незнання кусати людей, які згодом залежать від вашого коду. Як каже моя дружина: коли мова заходить про програмування ... практикуйте безпечний hex!


1
+1 Під час читання текстового файлу Python перевірку наявності нового рядка (або сліпого видалення його, якщо він існує line = line.rstrip('\n')) слід робити як окремий крок ДО розбору рядка на поля.
John Machin

6

Використання розуміння списку:

myList = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n']

[(el.strip()) for el in myList]

Це передбачає, що намір полягає у позбавленні всіх провідних та кінцевих пробілів. Це не точний збіг для "видалення нових кінцевих рядків".
Джим Денніс,


2

Як альтернативний метод, якщо ви знаєте, що у ваших даних немає пробілів, що, здається, так і є, ви можете використовувати split () (без аргументів). Це розділяється на пробіли та використовує більш ефективний алгоритм, ніж інша версія розділення. Він також позбавляє пробілу з обох кінців.

line = line.split()

І це все.


2

Ви могли б зробити -

DELIMITER = '\t'
lines = list()
for line in open('file.txt'):
    lines.append(line.strip().split(DELIMITER))

lines нього є весь вміст вашого файлу.

Можна також використовувати розуміння списків, щоб зробити це більш компактним.

lines = [ line.strip().split(DELIMITER) for line in open('file.txt')]

я використовую варіант цього підходу, щоб перетворити файл на однорядкову змінну javascript. приємно. завдяки Srikar
Zach


2

str.strip () видаляє пробіли. Ви також можете передати власні символи як аргумент для зняття. Функція strip видаляє пробіли / власні символи з обох кінців рядка. lstrip () та rstrip () - це функція лівої смуги та правої смуги відповідно.

Наприклад:

test_str = "Vishaka\n" 
test_str = test_str.strip()

test_str тепер Вішака


1

Ви отримуєте доступ до останнього елемента набору, а потім зберігаєте значення у змінній.

Отже, у вас є:

fileName = '7.3\n'

тоді просто зробіть:

fileName.strip()

який вас залишить 7.3. Потім збережіть це значення назад в останньому елементі набору.

Ви можете використовувати lstrip()або, rstrip()щоб видалити лише ліву або праву сторону.


1

Оскільки питання OP стосується вилучення символу нового рядка з останнього елемента, я б скинув його за допомогою the_list[-1].rstrip():

>>> the_list = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n']
>>> the_list[-1] = ls[-1].rstrip()
>>> the_list
['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3']

Це O (1).


0

Це працює, щоб вилучити \n(новий рядок) з елемента зі списку, він просто знімає перший елемент у рядку

def remove_end(s):
    templist=[]
    for i in s:
        templist.append(i)
    return(templist[0])

0

Я мав цю проблему і вирішив її за допомогою описаної вище функції chomp:

def chomp(s):
    return s[:-1] if s.endswith('\n') else s

def trim_newlines(slist):
    for i in range(len(slist)):
        slist[i] = chomp(slist[i])
    return slist
.....
names = theFile.readlines()
names = trim_newlines(names)
....

1
Це здається просто дублікатом попередніх відповідей. Якщо воно щось додає, чітко поясніть, що це таке.
blm

0

Для обробки багатьох розділювачів нового рядка, включаючи комбінації символів, наприклад \r\n, використовуйте розділені лінії . Об’єднайте об’єднання та розділені лінії, щоб видалити / замінити всі нові рядки із рядка s:

''.join(s.splitlines())

Щоб видалити рівно один кінцевий новий рядок, передайте Trueяк keependsаргумент збереження роздільників, видаливши лише роздільники в останньому рядку:

def chomp(s):
    if len(s):
        lines = s.splitlines(True)
        last = lines.pop()
        return ''.join(lines + last.splitlines())
    else:
        return ''

0
new_list = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n']
for i in range(len(new_list)):
    new_list[i]=new_list[i].replace('\n','')
print(new_list)

Результат буде таким

['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3']
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.