51

私は現在、SciPy.integrate.odeを使用してPythonで複雑な微生物食物網を実装しています。システムに種や反応を簡単に追加する機能が必要なので、非常に一般的なものをコーディングする必要があります。私のスキームは次のようになります。

class Reaction(object):
    def __init__(self):
        #stuff common to all reactions
    def __getReactionRate(self, **kwargs):
        raise NotImplementedError

... Reaction subclasses that 
... implement specific types of reactions


class Species(object):
    def __init__(self, reactionsDict):
        self.reactionsDict = reactionsDict
        #reactionsDict looks like {'ReactionName':reactionObject, ...}
        #stuff common to all species

    def sumOverAllReactionsForThisSpecies(self, **kwargs):
        #loop over all the reactions and return the 
        #cumulative change in the concentrations of all solutes

...Species subclasses where for each species
... are defined and passed to the superclass constructor

class FermentationChamber(object):
    def __init__(self, speciesList, timeToSolve, *args):
        #do initialization

    def step(self):
        #loop over each species, which in turn loops 
        #over each reaction inside it and return a 
        #cumulative dictionary of total change for each 
        #solute in the whole system


if __name__==__main__:
    f = FermentationChamber(...)

    o  = ode(...) #initialize ode solver

    while o.successful() and o.t<timeToSolve:
         o.integrate()

    #process o.t and o.y (o.t contains the time points
    #and o.y contains the solution matrix)

したがって、問題は、との辞書を反復処理するときにSpecies.sumOverAllReactionsForThisSpecies()FermentationChamber.step()最初と最後の反復の間に辞書に要素が追加または削除されない場合、辞書の反復順序が同じであることが保証されるかどうかです。つまり、辞書から各反復で作成されるnumpy配列の順序は変わらないと想定できますか?たとえば、ディクショナリの形式が{'Glucose':10、'Fructose':12}の場合、このディクショナリから作成された配列の順序は常に同じになります(順序が何であっても、それは決定論的です)。

メガポストで申し訳ありませんが、私がどこから来たのかをお知らせしたいと思います。

4

6 に答える 6

76

はい、変更されていない場合、同じ順序が保証されます。

こちらのドキュメントを参照してください。

編集:

値の変更 (キーの追加/削除ではなく) が順序に影響するかどうかについては、C ソースのコメントに次のように記載されています。

/* CAUTION: PyDict_SetItem() must guarantee that it won't resize the
 * dictionary if it's merely replacing the value for an existing key.
 * This means that it's safe to loop over a dictionary with PyDict_Next()
 * and occasionally replace a value -- but you can't insert new keys or
 * remove them.
 */

実装の詳細ではなく、言語の要件のようです。

于 2010-01-12T22:43:49.323 に答える
8

辞書に変更が加えられていない場合、答えは「はい」です。こちらのドキュメントをご覧ください

ただし、Pythonでは辞書は本質的に順序付けられていません。一般に、機密性の高いソート済みデータを辞書に依存することはベストプラクティスではありません。

より堅牢なソリューションの例は、DjangoのSortedDictデータ構造です。

于 2010-01-12T22:49:02.887 に答える
7

順序を一貫させたい場合は、特定の順序を強制するために何かをします。注文が保証されていることを確信できるかもしれませんし、正しいかもしれませんが、それは私には壊れやすいように見え、他の開発者にとっては不思議です。

たとえば、質問では常に強調します。Python 2.5と2.6で同じ順序であることが重要ですか?2.6および3.1?CPythonとJython?私はそれらを当てにしません。

于 2010-01-12T22:49:12.763 に答える
6

また、辞書の順序がランダムではないという事実に依存しないことをお勧めします。

辞書をソートする組み込みのソリューションが必要な場合は、http://www.python.org/dev/peps/pep-0265/を読んでください

最も関連性の高い資料は次のとおりです。

この PEP は、Py2.4 の sorted() 組み込み関数によってその必要性がほぼ満たされているため、拒否されます。

    >>> sorted(d.iteritems(), key=itemgetter(1), reverse=True)
    [('b', 23), ('d', 17), ('c', 5), ('a', 2), ('e', 1)]

or for just the keys:

    >>> sorted(d, key=d.__getitem__, reverse=True)
    ['b', 'd', 'c', 'a', 'e']

Also, Python 2.5's heapq.nlargest() function addresses the common use
case of finding only a few of the highest valued items:

    >>> nlargest(2, d.iteritems(), itemgetter(1))
    [('b', 23), ('d', 17)]
于 2010-01-12T22:54:33.857 に答える
3

Python 3.1 には、この目的で使用できるcollections.OrderedDictクラスがあります。また、非常に効率的です。「すべてのメソッドの Big-O 実行時間は、通常の辞書の場合と同じです。」

OrderedDict自体のコードは Python 2.x と互換性がありますが、一部の継承されたメソッド ( _abcollモジュールから) は Python 3 のみの機能を使用します。ただし、最小限の労力で 2.x コードに変更できます。

于 2010-01-13T05:30:13.073 に答える