Как удалить \ n из элемента списка? - PullRequest
62 голосов
/ 03 октября 2010

Я пытаюсь получить Python для строки чтения из файла .txt и записать элементы первой строки в список.Элементы в файле были разделены табуляцией, поэтому я использовал split("\t") для разделения элементов.Поскольку в файле .txt много элементов, я сохранил данные, найденные в каждой строке, в отдельный список.

Проблема, с которой я столкнулся на данный момент, заключается в том, что каждый список отображается так:1006 * Как мне удалить \n из последнего элемента списка и сделать его просто '7.3'?

Ответы [ 15 ]

121 голосов
/ 03 октября 2010

Если вы хотите удалить \n только из последнего элемента, используйте это:

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

Если вы хотите удалить \n из всех элементов, используйте это:

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

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

line = line.strip()
# split line...
34 голосов
/ 17 июня 2015

Начиная с Python3 и далее

map больше не возвращает list, а mapObject, поэтому ответ будет выглядеть примерно так:

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

Подробнее об этом можно прочитать на Что нового в Python 3.0 .

map() и filter() возвращают итераторы.Если вам действительно нужен list, быстрое исправление, например, list(map(...))

Итак, каковы способы получения этого?


Случай 1 - list вызов по map с lambda

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 без lambda

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% быстрее.Таким образом, подход без использования 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 - Понимания списка

A Понимание списка здесь также возможно и аналогичнов 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 - худший.Но опять же --- ТОЛЬКО В PYTHON3

10 голосов
/ 03 октября 2010

Звучит так, будто вы хотите что-то вроде функции 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')

Очевидно, что вы никогда не должны видеть такую ​​строку, возвращаемую методами readline() или readlines() обычного объекта Python-файла.

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

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

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

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

Эта ошибка в учете текстовых файлов, заканчивающихся не символами новой строки, преследует многие утилиты UNIX и языки сценариев в течение многих лет.Это глупая ошибка в углу, которая проникает в код достаточно часто, чтобы быть вредным организмом, но не настолько, чтобы люди могли извлечь из нее урок.Мы можем утверждать, что «текстовые» файлы без окончательного перевода строки являются «поврежденными» или нестандартными;и это может быть допустимо для некоторых спецификаций программирования.

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

5 голосов
/ 03 октября 2010

Использование списка понимания:

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

[(el.strip()) for el in myList]
3 голосов
/ 03 сентября 2012

с этой ссылки :

Вы можете использовать метод rstrip (). Пример

mystring = "hello\n"    
print(mystring.rstrip('\n'))
2 голосов
/ 06 августа 2012

Это тоже будет работать,

f=open('in.txt','r')

    for line in f:
            parline = line[:-1].split(',')
2 голосов
/ 03 октября 2010

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

Например:

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

test_str сейчас Vishaka

2 голосов
/ 03 октября 2010

Вы могли бы сделать -

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')]
2 голосов
/ 03 октября 2010

В качестве альтернативного метода, если вы знаете, что в ваших данных нет пробелов, что, как кажется, имеет место, вы можете использовать split () (без аргументов). Это разделяет пустое пространство и использует более эффективный алгоритм, чем другая версия разбиения. Он также удаляет пробелы с обоих концов.

line = line.split()

И это все.

1 голос
/ 03 октября 2010

Вы получаете доступ к последнему элементу набора и затем сохраняете значение в переменной.

Итак, у вас есть:

fileName = '7.3\n'

, затем просто выполните:

fileName.strip()

, который оставит вас с 7.3.Затем сохраните это значение в последнем элементе набора.

Вы можете использовать lstrip() или rstrip(), чтобы удалить только левую или правую сторону.

...