.txtファイルから読み取り行にPythonを取得し、最初の行の要素をリストに書き込もうとしています。ファイル内の要素はタブで区切られているため、split("\t")
を使用して要素を区切りました。 .txtファイルには多くの要素があるため、各行にあるデータを個別のリストに保存しました。
私が現在抱えている問題は、次のような各リストを表示していることです。
['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n']
リストの最後の要素から\n
を削除して、単に'7.3'
にするにはどうすればよいですか?
最後の要素からのみ\n
を削除する場合は、これを使用します:
t[-1] = t[-1].strip()
すべての要素から\n
を削除する場合は、これを使用します。
t = map(lambda s: s.strip(), t)
\n
beforeを削除して行を分割することも検討できます。
line = line.strip()
# split line...
map
はlist
ではなくmapObject
を返すようになったため、答えは次のようになります
>>> map(lambda x:x.strip(),l)
<map object at 0x7f00b1839fd0>
詳しくは What's New In Python 3. をご覧ください。
map()
およびfilter()
は反復子を返します。本当にlist
が必要な場合、簡単な修正方法は次のとおりです。list(map(...))
では、これをどのように解決するのですか?
list
がmap
でlambda
を呼び出すmap
はiteratorを返します。 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マイクロ秒。それはそれほど悪くはありません。しかし、もっと効率的な方法はありますか?
list
がmap
なしで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
を使用しないアプローチの方が適しています。
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
句よりも間違いなく読みやすいです。
ここでも リスト内包表記 も使用でき、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
の代わりにリスト内包表記を使用します
最後の方法は、リスト自体の内部で変更を行うことです。これにより、多くのメモリスペースが節約されます。これは 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のみ
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ユーティリティとスクリプト言語を悩ませてきました。これは愚かなコーナーベースのバグであり、害虫になるほど頻繁にコードに忍び込みますが、人々がそれから学ぶのに十分ではありません。最終的な改行のない「テキスト」ファイルは「破損」または非標準であると主張できます。それは、一部のプログラミング仕様で有効な場合があります。
しかし、コーディングのコーナーケースを無視して、その無知が後でコードに依存している人を噛むのは非常に簡単です。私の妻が言っているように、プログラミングに関しては...安全なヘックスを練習してください!
リスト内包表記の使用:
myList = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n']
[(el.strip()) for el in myList]
これも機能しますが、
f=open('in.txt','r')
for line in f:
parline = line[:-1].split(',')
別の方法として、データにスペースがないことがわかっている場合はそうであると思われますが、split()を(引数なしで)使用できます。これは空白で分割され、他のバージョンの分割よりも効率的なアルゴリズムを使用します。また、両端から空白を取り除きます。
line = line.split()
以上です。
あなたができる-
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')]
str.strip()は空白文字を削除します。 stripに引数としてカスタム文字を渡すこともできます。 strip関数は、文字列の両端の空白/カスタム文字を削除します。 lstrip()およびrstrip()は、それぞれ左ストリップおよび右ストリップ関数です。
例えば:
test_str = "Vishaka\n"
test_str = test_str.strip()
test_strがビシャカになりました
セットの最後の要素にアクセスし、値を変数に保存します。
だからあなたが持っています:
fileName = '7.3\n'
それから:
fileName.strip()
7.3
が残ります。次に、その値をセットの最後の要素に保存します。
lstrip()
またはrstrip()
を使用して、左側または右側のみを削除できます。
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)です。
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']
\r\n
などの文字の組み合わせを含む多くの改行区切り文字を処理するには、 splitlines を使用します。 join と splitlines を組み合わせて、文字列s
からすべての改行を削除/置換します。
''.join(s.splitlines())
厳密に1つ末尾改行を削除するには、True
をkeepends
として渡します引数を使用して区切り文字を保持し、最後の行の区切り文字のみを削除します。
def chomp(s):
if len(s):
lines = s.splitlines(True)
last = lines.pop()
return ''.join(lines + last.splitlines())
else:
return ''
これは、リスト内のアイテムから\n
(新しい行)を取り出すために機能し、文字列の最初のアイテムをオフにします
def remove_end(s):
templist=[]
for i in s:
templist.append(i)
return(templist[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)
....