input = "foo ,,bar ,baz,"
tags = [x.strip() for x in input.split(',') if len(x.strip()) > 0]
必要な出力は、明らかに空の文字列を含まないリストです。
問題は、マイクロ最適化の精神にあります。strip()
候補者x
を2回、つまり1回はテスト用、もう1回は追加用にしない方法はありますか?
言い換えると、2回の作業を行わなくても、リストに追加できる値を式に生成できますか?
input = "foo ,,bar ,baz,"
tags = [x.strip() for x in input.split(',') if len(x.strip()) > 0]
必要な出力は、明らかに空の文字列を含まないリストです。
問題は、マイクロ最適化の精神にあります。strip()
候補者x
を2回、つまり1回はテスト用、もう1回は追加用にしない方法はありますか?
言い換えると、2回の作業を行わなくても、リストに追加できる値を式に生成できますか?
新しい文字列の作成は、スキャンするよりも常にコストがかかります。x.isspace()
最初の非スペース文字が検出された後に戻ります
tags = [x.strip() for x in input.split(',') if x and not x.isspace()]
text = 'foo ,,bar ,baz,'
(私はビルトインの名前としてではtext
なく使用します。ビルトインをシャドウイングすることは避けてください。)input
input
まず第一に、len(x.strip()) > 0
単純に(そしてより効率的に)として書くことができますx.strip()
。
tags = [x.strip() for x in text.split(',') if x.strip()]
あなたが本当にしたいのであれば、あなたは一度だけストリップをすることができます、しかしそれがより速いかどうかはわかりません:
tags = [x for x in (x.strip() for x in text.split(',')) if x]
あなたが本当にしたいのなら、あなたはそれを機能的にすることさえできます...
tags = filter(bool, map(lambda x: x.strip(), text.split(',')))
パフォーマンスの数値:
>>> from timeit import timeit
>>> timeit(lambda: [x.strip() for x in text.split(',') if x.strip()])
1.9443869590759277
>>> timeit(lambda: [x for x in (x.strip() for x in text.split(',')) if x])
2.1135239601135254
>>> timeit(lambda: filter(bool, map(lambda x: x.strip(), text.split(','))))
2.52907395362854
ご覧のとおり、最初のものが最速です。
これも機能します...
text = "foo ,,bar ,baz,"
text.replace(',',' ').split()