2

キーと値のペアを反転し、OrderedDictを反転するワンライナーを作成しようと何度も試みた後、次のようになりました。

    from collections import OrderedDict as OD

    attributes=OD((('brand','asus'), ('os','linux'), ('processor','i5'), ('memory','4G')))
    print(attributes)

    reversed_attributes=OD(reversed(list(attributes.items())))
    print(reversed_attributes)

    inverted_attributes=OD([reversed(item) for item in attributes.items()])
    print(inverted_attributes)

    ''' Prints 
        OrderedDict([('brand', 'asus'), ('os', 'linux'), ('processor', 'i5'), ('memory', '4G')])
        OrderedDict([('memory', '4G'), ('processor', 'i5'), ('os', 'linux'), ('brand', 'asus')])
        OrderedDict([('asus', 'brand'), ('linux', 'os'), ('i5', 'processor'), ('4G', 'memory')])
    '''

これは機能しますが、非効率的ですか?reverse(list(a.items()))を使用することにより、これは多くのオーバーヘッドを作成するので、pythonicではありませんか?Converted_attributesについても同じです。

ポイントはforループなどを避けることでしたが、スケールアップするとパフォーマンスが低下しますか?

4

2 に答える 2

4

興味深い私は他の方法も思いつきました。

>>> from collections import OrderedDict as OD
>>> attributes = OD((('brand','asus'), ('os','linux'), ('processor','i5'), ('memory','4G')))

逆にしたい場合は、これを行うことができます

>>> reverse = OD(attributes.items()[::-1])

またはよりpythonicなアプローチ:

>>> reverse = OD(reversed(attributes.items()))

listアイテムを作成する必要はないことに注意してくださいはすでにリストであり、whilereversedジェネレーターOrderedDictは単純に反復して新しい dict を生成します。

どちらも同様のタイミングを生成します。

$ python -m timeit "from collections import OrderedDict as OD; attributes = OD((('brand','asus'), ('os','linux'), ('processor','i5'), ('memory','4G')))" "reverse = OD(attributes.items()[::-1])"
10000 loops, best of 3: 54.8 usec per loop
$ python -m timeit "from collections import OrderedDict as OD; attributes = OD((('brand','asus'), ('os','linux'), ('processor','i5'), ('memory','4G')))" "reverse = OD(reversed(attributes.items()))"
10000 loops, best of 3: 54.4 usec per loop
$ python -m timeit "from collections import OrderedDict as OD; attributes = OD((('brand','asus'), ('os','linux'), ('processor','i5'), ('memory','4G')))" "reversed_attributes=OD(reversed(list(attributes.items())))"
10000 loops, best of 3: 54.4 usec per loop

反転したい場合:

>>> invert = OD(zip(*zip(*attributes.items())[::-1]))

以上の pythonic:

>>> invert = OD(map(reversed, attributes.items()))

両方とも同様のタイミングを生成します。

$ python -m timeit "from collections import OrderedDict as OD; attributes = OD((('brand','asus'), ('os','linux'), ('processor','i5'), ('memory','4G')));" "invert = OD(zip(*zip(*attributes.items())[::-1]))"
10000 loops, best of 3: 57 usec per loop
$ python -m timeit "from collections import OrderedDict as OD; attributes = OD((('brand','asus'), ('os','linux'), ('processor','i5'), ('memory','4G')));" "invert = OD(map(reversed, attributes.items()))"
10000 loops, best of 3: 56.8 usec per loop
$ python -m timeit "from collections import OrderedDict as OD; attributes = OD((('brand','asus'), ('os','linux'), ('processor','i5'), ('memory','4G')));" "inverted_attributes=OD([reversed(item) for item in attributes.items()])"
10000 loops, best of 3: 55.8 usec per loop

2 つの方法を組み合わせて使用​​すると、リバースと反転の両方を行うことができます。

これは機能しますが、非効率的ですか?reversed(list(a.items())) を使用することで、これは多くのオーバーヘッドを生み出しているので、pythonic ではありませんか? Inverted_attributes についても同じです。

何かが多くのオーバーヘッドを生成し、Pythonic である可能性がある一方で、何かが非常に効率的であり、あまり Pythonic ではない場合があります。この用語は少し乱用されていますが、それは私の意見です

ウィキペディアから発揮する:

Python コミュニティでよく使われる造語は pythonic です。これは、プログラム スタイルに関連する幅広い意味を持つ可能性があります。コードが pythonic であるということは、Python のイディオムをうまく使っている、自然である、または言語に流暢であるということです。同様に、インターフェイスまたは言語機能について Pythonic であると言うのは、それが Python のイディオムとうまく機能し、その使用が言語の残りの部分とうまく調和していると言うことです。

対照的に、Python ではないコードの特徴は、Python で C++ (または Lisp、Perl、または Java) コードを書こうとすることです。Pythonicity の概念は、Python のミニマリスト哲学である可読性と「それを行うには複数の方法がある」アプローチを回避することと密接に結びついています。読めないコードや理解できないイディオムは非 Pythonic です。

はどうかと言うと:

しかし、スケールアップするとパフォーマンスが低下しますか?

なぜそのような変換を行っているのか、またはそれらがシステムの不可欠な部分であるかどうかを知らずに、これを言うのは難しいです。エントリの数は小さいままで、問題はありませんが、これが Web サーバーで発生すると仮定して、リクエストのたびに大きな辞書でこれを行っている場合、これは非常に厳しいものになる可能性があり、これを回避するために再設計が必要になる場合があります。

于 2012-08-08T07:44:34.967 に答える