私はpythonの文字列のリストからすべての空の文字列を削除したいです。
私の考えはこのようになります:
while '' in str_list:
str_list.remove('')
これを行うための他のPythonic方法はありますか?
filter
:を使います。
str_list = filter(None, str_list) # fastest
str_list = filter(bool, str_list) # fastest
str_list = filter(len, str_list) # a bit slower
str_list = filter(lambda item: item, str_list) # slower than list comprehension
Python 3はfilter
からイテレータを返すので、list()
への呼び出しでラップする必要があります
str_list = list(filter(None, str_list)) # fastest
( など )
テスト:
>>> timeit('filter(None, str_list)', 'str_list=["a"]*1000', number=100000)
2.4797441959381104
>>> timeit('filter(bool, str_list)', 'str_list=["a"]*1000', number=100000)
2.4788150787353516
>>> timeit('filter(len, str_list)', 'str_list=["a"]*1000', number=100000)
5.2126238346099854
>>> timeit('[x for x in str_list if x]', 'str_list=["a"]*1000', number=100000)
13.354584932327271
>>> timeit('filter(lambda item: item, str_list)', 'str_list=["a"]*1000', number=100000)
17.427681922912598
strings = ["first", "", "second"]
[x for x in strings if x]
出力:['first', 'second']
編集:提案どおりに短縮
filterは実際にこれのための特別なオプションを持っています:
filter(None, sequence)
Falseと評価されたすべての要素を除外します。ここではbool、lenなどの実際の呼び出し可能オブジェクトを使用する必要はありません。
地図と同じくらい速い(bool、...)
>>> lstr = ['hello', '', ' ', 'world', ' ']
>>> lstr
['hello', '', ' ', 'world', ' ']
>>> ' '.join(lstr).split()
['hello', 'world']
>>> filter(None, lstr)
['hello', ' ', 'world', ' ']
時間を比較する
>>> from timeit import timeit
>>> timeit('" ".join(lstr).split()', "lstr=['hello', '', ' ', 'world', ' ']", number=10000000)
4.226747989654541
>>> timeit('filter(None, lstr)', "lstr=['hello', '', ' ', 'world', ' ']", number=10000000)
3.0278358459472656
filter(None, lstr)
はスペース' '
を持つ空の文字列を削除しません。' '.join(lstr).split()
は両方を削除しますが、''
を削除するだけです。
空白文字列を削除してfilter()
を使用するには、もっと時間がかかります。
>>> timeit('filter(None, [l.replace(" ", "") for l in lstr])', "lstr=['hello', '', ' ', 'world', ' ']", number=10000000)
18.101892948150635
If xの代わりに、空の文字列を削除するためだけにif X!= ''を使用します。このような:
str_list = [x for x in str_list if x != '']
これはあなたのリストの中にNoneデータ型を保存します。また、あなたのリストが整数を持っていて、0がそれらのうちの1つであるならば、それはまた保存されます。
例えば、
str_list = [None, '', 0, "Hi", '', "Hello"]
[x for x in str_list if x != '']
[None, 0, "Hi", "Hello"]
@ Ib33Xからの返信は素晴らしいです。取り除いた後、空の文字列をすべて削除したい場合。あなたもストリップ法を使用する必要があります。それ以外の場合は、空白がある場合も空の文字列を返します。のように、 ""もその答えに有効です。だから、によって達成することができます。
strings = ["first", "", "second ", " "]
[x.strip() for x in strings if x.strip()]
これに対する答えは["first", "second"]
です。
代わりにfilter
メソッドを使いたい場合は、次のようにします。list(filter(lambda item: item.strip(), strings))
。これは同じ結果になります。
リストのサイズによっては、新しいリストを作成するのではなくlist.remove()を使用する方が最も効率的です。
l = ["1", "", "3", ""]
while True:
try:
l.remove("")
except ValueError:
break
これには、新しいリストを作成しないという利点がありますが、毎回最初から検索する必要があるという欠点があります。ただし、上記で提案したwhile '' in l
を使用するのとは異なり、''
(両方の方法の長所を維持する方法は確かにありますが、より複雑です)。
filter
を使う:
newlist=filter(lambda x: len(x)>0, oldlist)
指摘したようにフィルタを使用することの欠点は、それが他のものより遅いということです。また、lambda
は通常高価です。
あるいは、最も単純で最も反復的なものを選ぶことができます。
# I am assuming listtext is the original list containing (possibly) empty items
for item in listtext:
if item:
newlist.append(str(item))
# You can remove str() based on the content of your original list
これは最も直感的な方法であり、まともな時間で行われます。
の空白を文字列 の中に入れたい場合は、いくつかの方法を使用して意図せずに空白を削除する可能性があります。このリストがあれば
['hello world'、 ''、 ''、 'hello']あなたが望むかもしれないもの['hello world'、 'hello']
最初にリストをトリムして、任意のタイプの空白を空の文字列に変換します。
space_to_empty = [x.strip() for x in _text_list]
それからそれらのリストから空の文字列を削除します
space_clean_list = [x for x in space_to_empty if x]
Aziz Altoによって報告されているようにfilter(None, lstr)
はスペース' '
を持つ空の文字列を削除しませんが、lstrが文字列のみを含むことが確実ならばfilter(str.strip, lstr)
を使用できます。
>>> lstr = ['hello', '', ' ', 'world', ' ']
>>> lstr
['hello', '', ' ', 'world', ' ']
>>> ' '.join(lstr).split()
['hello', 'world']
>>> filter(str.strip, lstr)
['hello', 'world']
私のPCの時間を比較する
>>> from timeit import timeit
>>> timeit('" ".join(lstr).split()', "lstr=['hello', '', ' ', 'world', ' ']", number=10000000)
3.356455087661743
>>> timeit('filter(str.strip, lstr)', "lstr=['hello', '', ' ', 'world', ' ']", number=10000000)
5.276503801345825
''
とスペース' '
を持つ空の文字列を削除する最も早い解決策は' '.join(lstr).split()
のままです。
コメントで報告されているように、文字列にスペースが含まれていると状況が異なります。
>>> lstr = ['hello', '', ' ', 'world', ' ', 'see you']
>>> lstr
['hello', '', ' ', 'world', ' ', 'see you']
>>> ' '.join(lstr).split()
['hello', 'world', 'see', 'you']
>>> filter(str.strip, lstr)
['hello', 'world', 'see you']
filter(str.strip, lstr)
はスペースを含む文字列を保存しますが、' '.join(lstr).split()
はこの文字列を分割します。
ストリッピング後に空の部分をなくすには:
slist = map(lambda s: s and s.strip(), slist)
slist = filter(None, slist)
いくつかのPRO:
速く、選択的に組み込み関数と内包表記を使います。
def f1(slist):
slist = [s and s.strip() for s in slist]
return list(filter(None, slist))
def f2(slist):
slist = [s and s.strip() for s in slist]
return [s for s in slist if s]
def f3(slist):
slist = map(lambda s: s and s.strip(), slist)
return list(filter(None, slist))
def f4(slist):
slist = map(lambda s: s and s.strip(), slist)
return [s for s in slist if s]
%timeit f1(words)
10000 loops, best of 3: 106 µs per loop
%timeit f2(words)
10000 loops, best of 3: 126 µs per loop
%timeit f3(words)
10000 loops, best of 3: 165 µs per loop
%timeit f4(words)
10000 loops, best of 3: 169 µs per loop