Re: Self reordering list in Python
LRU caches are nice and simple, but if you want something fancier, with support for squid-like expiry models (ie, using mtime and atime to estimate a "stale time", and IMS fetches), you can have a look at my GCache; http://minkirri.apana.org.au/~abo/projects/GCache Even if you don't want something that fancy, it uses a PQueue priority queue to achieve exactly what you want. I provide a pure-python implementation using bisect, but recommend a C extension module with the same name by Andrew Snare which uses a fibonacci heap (python-pqueue is the Debian Package). Note that python 2.3 introduced a heapq module that does for queue lists what bisect does for heap lists. I am planning to modify my PQueue to use it instead of bisect. -- http://mail.python.org/mailman/listinfo/python-list
Re: Self reordering list in Python
Actually, after posting this I did some more work on the PQueue modules I had, implementing both bisect and heapq versions. It turns out the bisect version is heaps faster if you ever delete or re-set values in the queue. The problem is heapq is O(N) for finding a particular entry in the Queue, and any time you change or remove something from it you need to heapify it again, which is also O(N). Andew Snare has a C PQueue extension module that is heaps faster from all angles. It uses a fibonacci heap and gets O(lg N) deletes and re-sets. I think it does this by using the dict to speed finding entries it in the heap, and uses some properties of the heap to "assign lower" efficiently. The queue used in the lrucache will also suffer from the O(N) problem when deleting or reseting values in the cache. -- http://mail.python.org/mailman/listinfo/python-list
Re: Life of Python
> Okay. This makes sense if the software is: > > 1) Designed by one institution. > 2) Designed almost entirely before deployment. > 3) Not designed to be worked on by users and > semi-trained developers. > > In other words --- proprietary software. In my experience, it doesn't work well even in these cases. Investing a huge amount of effort designing in detail well in advance is nearly always a mistake, unless the requirements are fully understood and static... ie never. Mostly the requirements are unknown until the (possibly internal) customer has something. Nothing identifies requirements better than deployment. Particularly with large projects that have long development times, even if the requirements are well understood at the start, they will have changed by the time it is deployed. The biggest and most common mistake with software development is believing that it finishes. Software has a lifecycle, and development is like food; it is constantly required, otherwise the software dies. -- Donovan Baarda -- http://mail.python.org/mailman/listinfo/python-list
Re: Magic Optimisation
Bengt Richter wrote: > On 5 Sep 2005 07:27:41 -0700, "Paul McGuire" <[EMAIL PROTECTED]> wrote: > > >I still think there are savings to be had by looping inside the > >try-except block, which avoids many setup/teardown exception handling > >steps. This is not so pretty in another way (repeated while on > >check()), but I would be interested in your timings w.r.t. your current [...] > Why not let popleft trigger an exception out of while True instead, > and prevent tasks from raising StopIteration, and let them yield a None > to indicate keep scheduling with no special action, and something else [...] The rule of thumb with exceptions is use them for infrequent events. If you keep to this you end up with clean and fast code. Provided task.next() raises StopIteration less than about 25% of the time it is called, it is cleaner and more efficient to use an exception than to return None. It is also more efficient to handle terminating by allowing popleft trigger an exception. Try the following; def loop(self): self_call_exit_funcs = self.call_exit_funcs self_pool_popleft = self.pool.popleft self_pool_append = self.pool.append while True: try: task = self_pool_popleft() task.next() self_pool_append(task) except StopIteration: self_call_exit_funcs(task) except IndexError: break There are other "optimisations" that could be applied that make this code faster but uglier. For example, putting another "while True: loop inside the try block to avoid the try block setup each iteration. Also, exception handling is slower when you specify the exception class (it has to check if the exception matches), so you might be able to arrange this with an anonymous accept: block around the task.next() to handle the StopIteration exception. Another thing that disturbs me is the popfirst/append every iteration. Depending on how many loops through all the tasks before one "finishes", you might find it more efficient to do this; def loop(self): self_pool = self.pool self_pool_remove = self_pool.remove self_call_exit_funcs = self.call_exit_funcs while self_pool: try: for task in self_pool: task.next() except: self_pool_remove(task) self_call_exit_funcs(task) -- http://mail.python.org/mailman/listinfo/python-list
Re: class attribute confusion
Am 03.12.2010 23:11, schrieb Arnaud Delobelle: OAN writes: Hi, i was having a problem with class attributes initiated outside of __init__. This code is a demonstration of what i mean: class A(): mylist = [] def __init__(self): self.mylist.append(1) pass class B(A): def __init__(self): A.__init__(self) self.mylist.append(2) v = A() print 'v:',v.mylist x = B() print 'x:',x.mylist y = B() print 'y:',y.mylist z = A() print 'z:',z.mylist print 'v:',v.mylist I would expect the following result: v: [1] x: [1, 2] y: [1, 2] z: [1] v: [1] Who wouldn't, right? But actually python 2.6(.6) gives me the following result: v: [1] x: [1, 1, 2] y: [1, 1, 2, 1, 2] z: [1, 1, 2, 1, 2, 1] v: [1, 1, 2, 1, 2, 1] The four variables v,x,y and z now actually share the same 'mylist'!! To get the correct results, i have to initialize 'mylist' inside of the __init__ method! Yes. See below. I think this behaviour is totally wrong, since it seems A.__init__(self) is changing the value inside of A() not inside of the object variable 'self' (that should be x or y)!! It's not wrong at all. You expect "mylist" to behave as an instance attribute, but you defined it as a class attribute. Instance attributes are naturally initialised in the __init__() method. Could you please point me to a reference in the doc?? Thanks in advance. -- http://mail.python.org/mailman/listinfo/python-list
