3
input = "foo ,,bar ,baz,"
tags = [x.strip() for x in input.split(',') if len(x.strip()) > 0] 

必要な出力は、明らかに空の文字列を含まないリストです。

問題は、マイクロ最適化の精神にあります。strip()候補者xを2回、つまり1回はテスト用、もう1回は追加用にしない方法はありますか?

言い換えると、2回の作業を行わなくても、リストに追加できる値を式に生成できますか?

4

3 に答える 3

9

新しい文字列の作成は、スキャンするよりも常にコストがかかります。x.isspace()最初の非スペース文字が検出された後に戻ります

tags = [x.strip() for x in input.split(',') if x and not x.isspace()]
于 2012-05-23T23:00:15.643 に答える
3
text = 'foo ,,bar ,baz,'

(私はビルトインの名前としてではtextなく使用します。ビルトインをシャドウイングすることは避けてください。)inputinput

まず第一に、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

ご覧のとおり、最初のものが最速です。

于 2012-05-23T22:52:52.540 に答える
1

これも機能します...

 text = "foo ,,bar ,baz,"
 text.replace(',',' ').split()
于 2012-05-23T23:21:45.437 に答える