0

次のコードがあります。

from functions import *

powers = AutoVivification()
powers[1] = {'c1': 0.5, 'gamma': 1, 'lambda': 1, 'A': 1}

print powers[1]

私のautovivificationは次のとおりです(から取得:入れ子になった辞書を実装する最良の方法は何ですか?):

class AutoVivification(dict):
    """Implementation of perl's autovivification feature."""
    def __getitem__(self, item):
        try:
            return dict.__getitem__(self, item)
        except KeyError:
            value = self[item] = type(self)()
            return value

次のように出力します。

{'A': 1, 'c1': 0.5, 'gamma': 1, 'lambda': 1}

順序が変更されていることに注意してください。現在はアルファベット順です。これが起こらないようにする方法はありますか?申し訳ありませんが、十分に明確ではありませんでした:(キーを変更せずに、「任意に辞書を非常に簡単に拡張する」というautovivificationのプロパティを使用します)

4

3 に答える 3

3

ドキュメントが言うように:

キーと値は任意の順序で繰り返されます。これはランダムではなく、Python の実装によって異なり、辞書の挿入と削除の履歴に依存します。

つまり、辞書には固有の順序がありません。そして、複雑な追加要素を一切使わずにそれを見ることができます:

>>> print {'c1': 0.5, 'gamma': 1, 'lambda': 1, 'A': 1}
{'A': 1, 'c1': 0.5, 'gamma': 1, 'lambda': 1}

挿入順にキーを保持する dict が必要な場合は、OrderedDict.


ただし、この場合、それだけでは十分ではありません。(任意の順序を持​​つ) a を作成しdictてから、それを an に渡すと、OrderedDict最初の任意の順序が凍結されるだけです。

>>> from collections import OrderedDict
>>> print OrderedDict({'c1': 0.5, 'gamma': 1, 'lambda': 1, 'A': 1})
OrderedDict([('A', 1), ('c1', 0.5), ('gamma', 1), ('lambda', 1)])

そのreprの は、初期値の順序で をOrderedDict作成する方法の手がかりを与えるはずです: 各要素がキーと値のペアであるシーケンスから作成します。OrderedDict

>>> print OrderedDict([('c1', 0.5), ('gamma', 1), ('lambda', 1), ('A', 1)])
OrderedDict([('c1', 0.5), ('gamma', 1), ('lambda', 1), ('A', 1)])

を自動有効化したい場合は、既存のクラスの代わりに をOrderedDict使用して実行できます。ただし、使用しているクラスには考慮すべき問題がいくつかあります。特に、親クラスのメソッドで従来のスタイルの呼び出しではなく、実際に使用したい場合。それを行っていれば、定義するだけで完了できます。また、あなたのクラスがそのままでは適切にピクルスになるとは思いません。OrderedDictdictsuperclass AutoVivifiedOrderedDict(OrderedDict, AutoVivification): pass


自動有効化に を使用する場合defaultdict、トリッキーな部分はすべて既に処理されています。

def AutoVivification():
    return defaultdict(AutoVivification)

それに順序を追加する場合は、が必要になるOrderedDefaultDictため、次のようにできます。

def OrderedAutoVivification():
    return OrderedDefaultDict(AutoVivification)

自分で作る方法がわからない場合はOrderedDefaultDict、レシピを検索してください。(ほとんどの場合、両方のクラスから継承できます…シグネチャが異なるという事実を除いて、そのため、どの__init__ように見えるべきかを考え、適切な引数で適切な基本初期化子を明示的に呼び出す必要があります。議論については、この質問を参照してください。 )

于 2013-12-12T19:54:54.907 に答える
-1

辞書は Python では順序付けされていません。一度並べ替えた順序は保持されません。代わりに、

from collections import OrderedDict

powers = OrderedDict()
powers[1] = {'c1': 0.5, 'gamma': 1, 'lambda': 1, 'A': 1}

print powers[1]
于 2013-12-12T19:36:26.647 に答える
-4

別のキーを追加して順序を指定できます...

import operator

powers = {0: ['c1', 0.5], 1: ['gamma', 1], 2: ['lambda', 1], 3: ['A', 1]}
print sorted(powers.items(), key=operator.itemgetter(0))

お役に立てれば!

于 2013-12-12T19:36:40.493 に答える