2010-01-12 30 views
21

Tôi hiện đang triển khai một trang web thực phẩm vi sinh phức tạp bằng Python sử dụng SciPy.integrate.ode. Tôi cần khả năng dễ dàng thêm loài và phản ứng vào hệ thống, vì vậy tôi phải viết mã một cái gì đó khá chung chung. chương trình của tôi trông giống như sau:Thứ tự của một từ điển Python có được đảm bảo lặp lại không?

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) 

Vì vậy, câu hỏi là, khi tôi lặp qua các từ điển trong Species.sumOverAllReactionsForThisSpecies()FermentationChamber.step(), là thứ tự lần lặp của từ điển đảm bảo để được như vậy nếu không có yếu tố được thêm vào hoặc gỡ bỏ từ các từ điển giữa lần lặp đầu tiên và lần lặp lại cuối cùng? Đó là, tôi có thể giả định rằng thứ tự của mảng numpy được tạo ra ở mỗi lần lặp lại từ từ điển sẽ không thay đổi? Ví dụ: nếu từ điển có định dạng {'Glucose': 10, 'Fructose': 12}, nếu một Mảng được tạo từ từ điển này sẽ luôn là có cùng thứ tự (không quan trọng thứ tự đó là gì, như miễn là nó xác định).

Xin lỗi vì bài đăng lớn, tôi chỉ muốn cho bạn biết tôi đến từ đâu.

+0

@ChinmayKanchi bạn có phiền không nếu tôi chỉnh sửa rất nhiều câu hỏi này? Tất cả các chi tiết về mạng lưới thức ăn và tích hợp ODEs không liên quan gì đến câu hỏi, đó là một câu hỏi rất hay và quan trọng. – LondonRob

Trả lời

4

Python 3.1 có một lớp collections.OrderedDict có thể được sử dụng cho mục đích này. Nó cũng rất hiệu quả: "Big-O thời gian chạy cho tất cả các phương pháp đều giống như từ điển thông thường."

Bản thân số code for OrderedDict tương thích với Python 2.x, mặc dù một số phương pháp kế thừa (từ mô-đun _abcoll) sử dụng các tính năng chỉ có Python 3. Tuy nhiên, chúng có thể được sửa đổi thành mã 2.x với nỗ lực tối thiểu.

+1

Điều này không thực sự trả lời câu hỏi, và sử dụng OrderedDict sẽ, trong khi cũng đảm bảo đặt hàng xác định, tăng sử dụng tài nguyên (không chắc chắn trong cách chính xác, mặc dù). Như câu trả lời khác cho thấy, một dict bình thường đã có bảo lãnh này, vì vậy không cần phải sử dụng OrderedDict (cho usecase cụ thể này). –

43

Có, cùng một thứ tự được đảm bảo nếu nó không được sửa đổi.

Xem tài liệu here.

Edit:

Về nếu thay đổi giá trị (nhưng không thêm/gỡ bỏ một key) sẽ ảnh hưởng đến trật tự, đây là những gì các chú thích trong C-nguồn tin cho biết:

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

Có vẻ như nó không phải là một chi tiết thực hiện, nhưng là một yêu cầu của ngôn ngữ.

+0

Ah, tuyệt vời! Tôi không chắc tôi có thể giải thích điều đó một cách chính xác không. Chỉ cần chắc chắn, nó không quan trọng nếu bản thân _values_ được sửa đổi, phải, miễn là các phím không? –

+2

Tôi khá chắc chắn "không có sửa đổi" có nghĩa là * không * sửa đổi, thời gian. Thay đổi các giá trị * có thể * thay đổi thứ tự sắp xếp từ điển. –

+0

Hư hỏng! Có vẻ như tôi sẽ phải suy nghĩ lại thuật toán đó. Có cơ sở hạ tầng kiểu bản đồ được sắp xếp theo thứ tự scipy/numpy hoặc thư viện chuẩn python không? Tôi không muốn phải phụ thuộc vào nhiều thư viện hơn tôi phải làm. –

8

Cung cấp không có sửa đổi được thực hiện cho từ điển, câu trả lời là có. See the docs here.

Tuy nhiên, các từ điển không bị ràng buộc bởi bản chất trong Python. Nói chung, đó không phải là phương pháp hay nhất để dựa vào từ điển cho dữ liệu được phân loại nhạy cảm.

Ví dụ về giải pháp mạnh mẽ hơn là Django's SortedDict data structure.

7

Nếu bạn muốn đơn hàng nhất quán, tôi sẽ làm gì đó để buộc một lệnh cụ thể. Mặc dù bạn có thể thuyết phục bản thân rằng thứ tự được đảm bảo, và bạn có thể đúng, nó có vẻ mong manh với tôi, và nó sẽ là bí ẩn đối với các nhà phát triển khác.

Ví dụ: bạn nhấn mạnh luôn là trong câu hỏi của mình. Điều quan trọng là nó có cùng thứ tự trong Python 2.5 và 2.6 không? 2.6 và 3.1? CPython và Jython? Tôi sẽ không tin vào những thứ đó.

+0

Chính xác! Sự mong manh của nó là những gì sẽ ngăn cản tôi làm điều đó ... –

+1

Điểm tốt. Tôi đã không chắc chắn như thế nào mong manh nó sẽ được khi tôi hỏi câu hỏi này. Một suy nghĩ lại của thuật toán này chắc chắn là theo thứ tự. –

5

Tôi cũng khuyên bạn không nên dựa vào thực tế thứ tự từ điển là không ngẫu nhiên.

Nếu bạn muốn có một xây dựng trong dung dịch để sắp xếp bạn điển đọc http://www.python.org/dev/peps/pep-0265/

Dưới đây là chất liệu phù hợp nhất:

PEP này bị từ chối vì sự cần thiết của nó đã được phần lớn thực hiện bởi Py2.Chức năng nội trang được sắp xếp của 4() được xây dựng:

>>> 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)] 
Các vấn đề liên quan