web-dev-qa-db-ja.com

リスト要素から\ nを削除する方法は?

.txtファイルから読み取り行にPythonを取得し、最初の行の要素をリストに書き込もうとしています。ファイル内の要素はタブで区切られているため、split("\t")を使用して要素を区切りました。 .txtファイルには多くの要素があるため、各行にあるデータを個別のリストに保存しました。

私が現在抱えている問題は、次のような各リストを表示していることです。

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

リストの最後の要素から\nを削除して、単に'7.3'にするにはどうすればよいですか?

63
Mr Wotan

最後の要素からのみ\nを削除する場合は、これを使用します:

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

すべての要素から\nを削除する場合は、これを使用します。

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

\nbeforeを削除して行を分割することも検討できます。

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

Python3以降

maplistではなくmapObjectを返すようになったため、答えは次のようになります

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

詳しくは What's New In Python 3. をご覧ください。

map()およびfilter()は反復子を返します。本当にlistが必要な場合、簡単な修正方法は次のとおりです。 list(map(...))

では、これをどのように解決するのですか?


ケース1-listmaplambdaを呼び出す

mapiteratorを返します。 list は、反復子をリストに変換できる関数です。したがって、listmap呼び出しでラップする必要があります。答えは次のようになります。

>>> 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-listmapなしでlambdaを呼び出す

lambdaは、Pythonコミュニティ( Guido を含む)の多くの人に嫌われています。それとは別に、プログラムの速度を大幅に低下させます。したがって、できる限りそれを避ける必要があります。トップレベル関数 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

素晴らしい。 2つの方法の効率の違いを確認できます。ほぼ60%高速です。したがって、ここではlambdaを使用しないアプローチの方が適しています。


ケース3-ガイドラインに従って、通常の方法

Python 3.0の新機能 からのもう1つの重要な点は、可能な限り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-インプレースメカニズムとスペース効率( T-M-T

最後の方法は、リスト自体の内部で変更を行うことです。これにより、多くのメモリスペースが節約されます。これは 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のみ

36
Bhargav Rao

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()メソッドによって返される文字列は決して表示されません。

私は、ファイルreadline()および同様の関数の結果から最後の文字を(s[:-1]スライスを使用して)盲目的に削除するのを見てきました。ファイルの最後の行でエラーが発生する可能性があるため、これは悪い考えです(ファイルが改行以外で終わる場合)。

最初に、読んだ行から最後の文字をむやみに取り除くと、誤った安心感に落ち着くかもしれません。通常のテキストエディターを使用してテストスイートファイルを作成する場合、ほとんどの行で最後の行の最後に改行がサイレントに追加されます。有効なテストファイルを作成するには、次のようなコードを使用します。

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

...そして、そのファイルを再度開いてreadline()またはreadlines()ファイルメソッドを使用すると、末尾の改行なしでテキストが読み取られることがわかります。

改行以外の文字で終わるテキストファイルを説明できないことは、長年にわたって多くのUNIXユーティリティとスクリプト言語を悩ませてきました。これは愚かなコーナーベースのバグであり、害虫になるほど頻繁にコードに忍び込みますが、人々がそれから学ぶのに十分ではありません。最終的な改行のない「テキスト」ファイルは「破損」または非標準であると主張できます。それは、一部のプログラミング仕様で有効な場合があります。

しかし、コーディングのコーナーケースを無視して、その無知が後でコードに依存している人を噛むのは非常に簡単です。私の妻が言っているように、プログラミングに関しては...安全なヘックスを練習してください!

11
Jim Dennis

リスト内包表記の使用:

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

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

これから リンク

rstrip()メソッドを使用できます。例

mystring = "hello\n"    
print(mystring.rstrip('\n'))
3
itagomo

これも機能しますが、

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

    for line in f:
            parline = line[:-1].split(',')
2
drunkbn

別の方法として、データにスペースがないことがわかっている場合はそうであると思われますが、split()を(引数なしで)使用できます。これは空白で分割され、他のバージョンの分割よりも効率的なアルゴリズムを使用します。また、両端から空白を取り除きます。

line = line.split()

以上です。

2
JoshD

あなたができる-

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

str.strip()は空白文字を削除します。 stripに引数としてカスタム文字を渡すこともできます。 strip関数は、文字列の両端の空白/カスタム文字を削除します。 lstrip()およびrstrip()は、それぞれ左ストリップおよび右ストリップ関数です。

例えば:

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

test_strがビシャカになりました

2
gopalkoduri

セットの最後の要素にアクセスし、値を変数に保存します。

だからあなたが持っています:

fileName = '7.3\n'

それから:

fileName.strip()

7.3が残ります。次に、その値をセットの最後の要素に保存します。

lstrip()またはrstrip()を使用して、左側または右側のみを削除できます。

1
Pavan

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)です。

1
Srisaila
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']
0
Tanmoy Datta

\r\nなどの文字の組み合わせを含む多くの改行区切り文字を処理するには、 splitlines を使用します。 joinsplitlines を組み合わせて、文字列sからすべての改行を削除/置換します。

''.join(s.splitlines())

厳密に1つ末尾改行を削除するには、Truekeependsとして渡します引数を使用して区切り文字を保持し、最後の行の区切り文字のみを削除します。

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

これは、リスト内のアイテムから\n(新しい行)を取り出すために機能し、文字列の最初のアイテムをオフにします

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

この問題が発生し、上記の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)
....
0
catchpolej