2010-01-12 13 views
21

मैं वर्तमान में SciPy.integrate.ode का उपयोग कर पाइथन में एक जटिल माइक्रोबियल खाद्य-वेब को कार्यान्वित कर रहा हूं। मुझे सिस्टम में प्रजातियों और प्रतिक्रियाओं को आसानी से जोड़ने की क्षमता की आवश्यकता है, इसलिए मुझे कुछ सामान्य को कोड करना होगा।क्या एक पायथन शब्दकोश का क्रम पुनरावृत्तियों पर गारंटी है?

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 सरणी का क्रम अलग-अलग नहीं होगा? उदाहरण के लिए, यदि किसी शब्दकोश में {'ग्लूकोज': 10, 'फक्रूटोज': 12} प्रारूप है, तो इस शब्दकोश से निर्मित एक ऐरे हमेशा एक ही ऑर्डर होगा (इससे कोई फ़र्क नहीं पड़ता कि वह ऑर्डर क्या है जब तक यह निर्धारिती है)।

मेगा-पोस्ट के लिए खेद है, मैं बस आपको यह बताने के लिए चाहता था कि मैं कहां से आ रहा हूं।

+0

@ChinmayKanchi क्या आपको बुरा लगता है अगर मैं इस सवाल को बड़े पैमाने पर संपादित करता हूं? खाद्य जाल और ओडीई को एकीकृत करने के बारे में सभी विवरणों के पास इस सवाल से कोई लेना देना नहीं है, जो कि एक बहुत अच्छा और महत्वपूर्ण है। – LondonRob

उत्तर

4

पायथन 3.1 एक collections.OrderedDict वर्ग कि इस उद्देश्य के लिए इस्तेमाल किया जा सकता है। यह भी बहुत ही कुशल है: "सभी विधियों के लिए बिग-ओ चलने का समय नियमित शब्दकोशों के समान होता है।"

code for OrderedDict स्वयं पाइथन 2.x के साथ संगत है, हालांकि कुछ विरासत विधियों (_abcoll मॉड्यूल से) पाइथन 3-केवल सुविधाओं का उपयोग करते हैं। हालांकि, उन्हें न्यूनतम प्रयास के साथ 2.x कोड में संशोधित किया जा सकता है।

+1

यह वास्तव में प्रश्न का उत्तर नहीं देता है, और ऑर्डर्ड डिक्ट का उपयोग करके, निर्धारिती क्रम की गारंटी भी देता है, संसाधन उपयोग में वृद्धि (निश्चित रूप से बिल्कुल सही तरीके से नहीं)। जैसा कि अन्य उत्तरों इंगित करते हैं, एक सामान्य नियम में पहले से ही यह गारंटी है, इसलिए ऑर्डर्ड डिक्ट (इस विशेष उपयोग के लिए) का उपयोग करने की आवश्यकता नहीं है। –

43

हां, वही आदेश गारंटीकृत है अगर इसे संशोधित नहीं किया गया है।

दस्तावेज़ here देखें।

संपादित करें:

मान बदलने (लेकिन नहीं जोड़ने/एक प्रमुख को हटाने) यदि आदेश को प्रभावित करेगा के बारे में, यह है कि क्या सी स्रोत में टिप्पणी कहते हैं:

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

ऐसा लगता है कि यह कार्यान्वयन विस्तार नहीं है, बल्कि भाषा की आवश्यकता है।

+0

आह, उत्कृष्ट! मुझे यकीन नहीं था कि मैं सही ढंग से इसका अर्थ दूंगा। बस यह सुनिश्चित करने के लिए, इससे कोई फर्क नहीं पड़ता कि _values_ स्वयं संशोधित हैं, ठीक है, जब तक कि चाबियाँ नहीं हैं? –

+2

मुझे पूरा यकीन है कि "कोई संशोधन नहीं" का मतलब है * नहीं * संशोधन, अवधि। मूल्यों को बदलना * शब्दकोश सॉर्ट ऑर्डर बदल सकता है। –

+0

दमन! ऐसा लगता है कि मुझे उस एल्गोरिदम पर पुनर्विचार करना होगा। क्या scipy/numpy या पायथन मानक लाइब्रेरी में एक आदेश दिया गया मानचित्र-प्रकार डेटास्ट्रक्चर है? मैं अधिक पुस्तकालयों पर निर्भर होना पसंद नहीं करना चाहता हूं। –

8

प्रदान किया गया कोई शब्दकोष शब्दकोश में किए गए हैं, जवाब हाँ है। See the docs here

हालांकि, शब्दकोश पाइथन में प्रकृति द्वारा अनियंत्रित हैं। सामान्य रूप से, संवेदनशील सॉर्ट किए गए डेटा के लिए शब्दकोशों पर भरोसा करना सबसे अच्छा अभ्यास नहीं है।

एक अधिक मजबूत समाधान का एक उदाहरण Django's SortedDict data structure होगा।

7

यदि आप आदेश को सुसंगत बनाना चाहते हैं, तो मैं एक विशेष आदेश को मजबूर करने के लिए कुछ करता हूं। यद्यपि आप स्वयं को यह समझाने में सक्षम हो सकते हैं कि आदेश की गारंटी है, और आप सही हो सकते हैं, यह मेरे लिए नाजुक लगता है, और यह अन्य डेवलपर्स के लिए रहस्यमय होगा।

उदाहरण के लिए, आप अपने प्रश्न में हमेशा पर जोर देते हैं। क्या यह महत्वपूर्ण है कि यह पाइथन 2.5 और 2.6 में एक ही आदेश हो? 2.6 और 3.1? सीपीथन और ज्योथन? मैं उन पर भरोसा नहीं करता।

+0

बिल्कुल! इसकी नाजुकता मुझे ऐसा करने से रोकती है ... –

+1

अच्छा बिंदु। मुझे यकीन नहीं था कि जब मैंने इस सवाल से पूछा तो यह कितना नाजुक होगा। इस एल्गोरिदम का एक पुनर्विचार निश्चित रूप से क्रम में है। –

5

मैं इस बात पर भरोसा करने की भी सिफारिश नहीं करता कि शब्दकोष आदेश गैर-यादृच्छिक है।

क्या आप http://www.python.org/dev/peps/pep-0265/

पढ़ा यहाँ सबसे अधिक प्रासंगिक सामग्री है शब्दकोश छँटाई के लिए एक समाधान में बनाया चाहते हैं:

यह पीईपी को अस्वीकार कर दिया है, क्योंकि यह काफी हद तक के लिए की जरूरत किया गया है Py2 द्वारा पूरा।4 के अनुसार क्रमबद्ध() builtin समारोह:

>>> 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)] 
संबंधित मुद्दे