1
def thing(mode, data):
    return [
        item for item in data
        if {
            'large': lambda item: item > 100,
            'small': lambda item: item < 100,
        }[mode](item)
    ]

このリスト内包表記は、ラムダの辞書を生成し、引数を介して 1 つのラムダを取得modeし、現在処理中のリスト項目に適用します。私の質問はこれです: これのパフォーマンス特性は何ですか?

listcomp の各反復中に、辞書全体がゼロから作成されますか? それとも、一度作成して各アイテムで使用しますか?

4

3 に答える 3

3

listcomp の各反復中に最初から作成された辞書全体です

はい。

それとも、一度作成して各アイテムで使用しますか?

いいえ。


幸いなことに、この場合(および私が考えることができる他のすべての場合)、前もって辞書を作成するのは簡単です:

 d = {
        'large': lambda item: item > 100,
        'small': lambda item: item < 100,
      }
 return [item for item in data if d[mode](item)]

あるいは、

func = {
        'large': lambda item: item > 100,
        'small': lambda item: item < 100,
        }[mode]
return [item for item in data if func(item)]
于 2013-03-13T02:05:00.223 に答える
2

これにより、リストの各要素に対して辞書全体が最初から作成されると確信しています。Python リスト内包表記の基本的な文法は次のとおりです。

[ E1 for ID in E2 if E3 ]

where E1, E2, and E3 are expressions. E2 is evaluated once, when the the interpreter starts to evaluate the list comprehension. E1 and E3 are evaluated for each member of the collection that E2 evaluates to. So, yes. In your question, the dictionary is constructed from scratch each time but you can easily fix that by declaring the dictionary before the list comprehension.

于 2013-03-13T02:06:11.797 に答える
1

辞書はループごとに 1 回作成され、辞書をキャッシュした場合よりもリストの理解が約 2 倍遅くなります。

>>> %timeit thing1('small', [1, 2, 3, 4, 5, 6])
100000 loops, best of 3: 2.4 us per loop
>>> %timeit thing2('small', [1, 2, 3, 4, 5, 6])
1000000 loops, best of 3: 1.06 us per loop

thing1はあなたの本来の機能でした。thing2は:

d = {
    'large': lambda item: item > 100,
    'small': lambda item: item < 100,
}

def thing3(mode, data):
    return list(filter(d[mode], data))

filter(f, data)の省略形ですitem for item in data if f(item)。Python 3 では、イテレータを作成します。イテレータは、反復するときにのみ項目を除外します。

于 2013-03-13T02:09:28.280 に答える