Pergunta

Atualmente estou implementando uma rede microbiana complexa em python usando Scipy.integrate.ode. Preciso da capacidade de adicionar facilmente espécies e reações ao sistema, por isso tenho que codificar algo bastante geral. Meu esquema se parece mais disso:

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)

Então, a questão é que quando eu itero sobre os dicionários em Species.sumOverAllReactionsForThisSpecies() e FermentationChamber.step(), a ordem de iteração dos dicionários é garantida como a mesma se nenhum elemento for adicionado ou removido dos dicionários entre a primeira e a última iteração? Ou seja, posso assumir que a ordem da matriz Numpy criada em cada iteração do dicionário não variará? Por exemplo, se um dicionário tiver o formato {'glicose': 10, 'frutose': 12}, se uma matriz criada a partir deste dicionário irá sempre Tenha a mesma ordem (não importa qual é essa ordem, desde que seja determinística).

Desculpe pelo mega-post, eu só queria que você soubesse de onde estou vindo.

Foi útil?

Solução

Python 3.1 tem um Coleções.OrderedDict classe que pode ser usada para esse fim. Também é muito eficiente: "Os tempos de corrida Big-O para todos os métodos são os mesmos que para dicionários regulares".

o Código para OrdeDDict em si é compatível com o python 2.x, embora alguns métodos herdados (do _abcoll módulo) Use recursos apenas do Python 3. No entanto, eles podem ser modificados para o código 2.x com um esforço mínimo.

Outras dicas

Sim, o mesmo pedido é garantido se não for modificado.

Veja os documentos aqui.

Editar:

Em relação à alteração do valor (mas não adicionar/remover uma chave), afetará a ordem, é isso que os comentários do C-Source diz:

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

Parece que não é um detalhe de implementação, mas um requisito do idioma.

Forneceu não Modificações são feitas no dicionário, a resposta é sim. Veja os documentos aqui.

No entanto, os dicionários não são ordenados pela natureza em Python. Em geral, não é a melhor prática confiar em dicionários de dados classificados sensíveis.

Um exemplo de uma solução mais robusta seria Estrutura de dados classificados de Django.

Se você deseja que a ordem seja consistente, eu faria algo para forçar uma ordem específica. Embora você possa se convencer de que a ordem é garantida, e você pode estar certo, parece frágil para mim, e será misterioso para outros desenvolvedores.

Por exemplo, você enfatiza sempre em sua pergunta. É importante que seja a mesma ordem em Python 2.5 e 2.6? 2.6 e 3.1? Cpython e Jython? Eu não contaria com isso.

Eu também recomendaria não confiar no fato de a ordem dos dicionários não ser aleatória.

Se você deseja uma solução embutida para classificar seu dicionário, leia http://www.python.org/dev/peps/pep-0265/

Aqui está o material mais relevante:

Este PEP é rejeitado porque a necessidade dele foi amplamente cumprida pela função construída () de 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)]
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top