Гарантируется ли порядок словаря Python в течение итераций?

StackOverflow https://stackoverflow.com/questions/2053021

Вопрос

В настоящее время я внедряю сложную микробную пищевую сеть на Python, используя SciPy.интегрировать.ода.Мне нужна возможность легко добавлять виды и реакции в систему, поэтому я должен закодировать что-то довольно общее.Моя схема выглядит примерно так:

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}, если массив, созданный на основе этого словаря, будет всегда имеют одинаковый порядок (не имеет значения, каков этот порядок, главное, чтобы он был детерминированным).

Извините за мега-пост, я просто хотел сообщить вам, откуда я берусь.

Это было полезно?

Решение

Python 3.1 имеет Коллекции.Упорядоченный запрет класс, который может быть использован для этой цели.Это тоже очень эффективно:"Время выполнения Big-O для всех методов такое же, как и для обычных словарей".

В код для OrderedDict сам по себе совместим с Python 2.x, хотя некоторые унаследованные методы (из _абколл модуль) используйте функции, доступные только для Python 3.Однако они могут быть изменены на код 2.x с минимальными усилиями.

Другие советы

Да, тот же порядок гарантируется, если он не будет изменен.

Смотрите документы здесь.

Редактировать:

Что касается того, повлияет ли изменение значения (но не добавление / удаление ключа) на порядок, это то, что говорится в комментариях в C-source:

/* 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.
 */

Похоже, что это не деталь реализации, а требование языка.

Предоставленный НЕТ в словарь внесены изменения, ответ - да. Смотрите документы здесь.

Однако словари в Python по своей природе неупорядочены.В общем, полагаться на словари для конфиденциальных отсортированных данных - не лучшая практика.

Примером более надежного решения могло бы быть Структура данных SortedDict от Django.

Если вы хотите, чтобы порядок был последовательным, я бы сделал что-нибудь, чтобы принудить к определенному порядку.Хотя вы могли бы убедить себя в том, что заказ гарантирован, и вы, возможно, правы, мне это кажется хрупким, и это будет загадкой для других разработчиков.

Например, вы подчеркиваете всегда в вашем вопросе.Важно ли, чтобы это был один и тот же порядок в Python 2.5 и 2.6?2.6 и 3.1?CPython и Jython?Я бы не стал на это рассчитывать.

Я также бы рекомендовал не полагаться на тот факт, что порядок словарей неслучаен.

Если вам нужно встроенное решение для сортировки вашего словаря, прочитайте http://www.python.org/dev/peps/pep-0265/

Вот наиболее актуальный материал:

Этот PEP отклоняется, потому что потребность в нем в значительной степени отпала выполняется встроенной функцией sorted() Py2.4:

    >>> 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)]
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top