次のような連結文字列があります。
my_str = 'str1;str2;str3;'
split
それに関数を適用してから、結果のリストをタプルに変換し、結果の空の文字列を取り除きたいと思いますsplit
(最後の「;」に注意してください)
これまでのところ、私はこれをやっています:
tuple(filter(None, my_str.split(';')))
それを行うためのより効率的な(速度とスペースの点で)方法はありますか?
これはどう?
tuple(my_str.split(';')[:-1])
('str1', 'str2', 'str3')
文字列を文字で分割し、;
すべての部分文字列 (最後の空の文字列を除く) を tuple に渡して、結果のタプルを作成します。
それはそれを行うための非常に合理的な方法です。いくつかの代替案:
foo.strip(";").split(";")
(文字列内に空のスライスが存在しない場合)[ x.strip() for x in foo.split(";") if x.strip() ]
(各スライスから空白を取り除くため)これを行う「最速」の方法は、多くのことに依存しますが、ipython で簡単に試すことができます%timeit
。
[1]: foo = "1;2;3;4;" [2]: %timeit foo.strip(";").split(";") 1000000 ループ、ベスト オブ 3: ループあたり 1.03 us [3]: %timeit filter(None, foo.split(';')) 1000000 ループ、ベストオブ 3: ループあたり 1.55 us
最後に空の文字列のみが必要な場合は、次のことができます。
a = 'str1;str2;str3;'
tuple(a.split(';')[:-1])
また
tuple(a[:-1].split(';'))
試すtuple(my_str.split(';')[:-1])
はい、それは非常に Pythonic な方法です。ジェネレーター式が好きな場合は、を次のように置き換えることもできますfilter()
。
tuple(part for part in my_str.split(';') if part)
これには、各パーツをインラインでさらに処理できるという利点があります。
のドキュメントに次のように記載されていることに注意してくださいstr.split()
。
... sep が指定されていないか、None の場合、空白文字列は区切り文字であり、空の文字列は結果から削除されます。
他のセパレーターを許可せずに、なぜこの特別なケースが行われたのだろうか...
分割してからスライスを使用します。
my_str.split(';')[:-1]
また :
lis=[x for x in my_str.split(';') if x]
これは古い質問であることは知っていますが、これに出くわしたところ、トップの回答 (David) が OP が要求したようなタプルを返さないことがわかりました。OPが示した1つの例に対して解決策は機能しますが、投票数が最も多い回答(Levon)は、末尾のセミコロンを部分文字列で削除します。これは、空の文字列でエラーになります。
最も堅牢でpythonicなソリューションはvoithosの答えです:
tuple(part for part in my_str.split(';') if part)
これが私の解決策です:
tuple(my_str.strip(';').split(';'))
ただし、空の文字列に対して実行すると、これが返されます。
('',)
したがって、私のものをvoithosの回答に置き換えます。ありがとうございます!