Re: Why is recursion so slow?
Nick Craig-Wood wrote: [snip] By definition any function in a functional language will always produce the same result if given the same arguments, so you can memoize any function. Ah, so that's why time.time() seems to be stuck... ;) Rich -- http://mail.python.org/mailman/listinfo/python-list
Re: opposite of zip()?
[EMAIL PROTECTED] wrote: Given a bunch of arrays, if I want to create tuples, there is zip(arrays). What if I want to do the opposite: break a tuple up and append the values to given arrays: map(append, arrays, tupl) except there is no unbound append() (List.append() does not exist, right?). list.append does exist (try the lower-case flavor). Without append(), I am forced to write a (slow) explicit loop: for (a, v) in zip(arrays, tupl): a.append(v) Except that isn't technically the opposite of zip. The opposite would be a tuple of single-dimensional tuples: def unzip(zipped): Given a sequence of size-sized sequences, produce a tuple of tuples that represent each index within the zipped object. Example: zipped = zip((1, 2, 3), (4, 5, 6)) zipped [(1, 4), (2, 5), (3, 6)] unzip(zipped) ((1, 2, 3), (4, 5, 6)) if len(zipped) 1: raise ValueError, 'At least one item is required for unzip.' indices = range(len(zipped[0])) return tuple(tuple(pair[index] for pair in zipped) for index in indices) This is probably not the most efficient hunk of code for this but this would seem to be the correct behavior for the opposite of zip and it should scale well. Modifying the above with list.extend would produce a variant closer to what I think you're asking for: def unzip_extend(dests, zipped): Appends the unzip versions of zipped into dests. This avoids an unnecessary allocation. Example: zipped = zip((1, 2, 3), (4, 5, 6)) zipped [(1, 4), (2, 5), (3, 6)] dests = [[], []] unzip_extend(dests, zipped) dests [[1, 2, 3], [4, 5, 6]] if len(zipped) 1: raise ValueError, 'At least one item is required for unzip.' for index in range(len(zipped[0])): dests[index].extend(pair[index] for pair in zipped) This should perform pretty well, as extend with a comprehension is pretty fast. Not that it's truly meaningful, here's timeit on my 2GHz laptop: bash-3.1$ python -m timeit -s 'import unzip; zipped=zip(range(1024), range(1024))' 'unzip.unzip_extend([[], []], zipped)' 1000 loops, best of 3: 510 usec per loop By comparison, here's the unzip() version above: bash-3.1$ python -m timeit -s 'import unzip; zipped=zip(range(1024), range(1024))' 'unzip.unzip(zipped)' 1000 loops, best of 3: 504 usec per loop Rich -- http://mail.python.org/mailman/listinfo/python-list
Re: opposite of zip()?
Matt Nordhoff wrote: [snip] As Paddy wrote, zip is its own unzip: zipped = zip((1, 2, 3), (4, 5, 6)) zipped [(1, 4), (2, 5), (3, 6)] unzipped = zip(*zipped) unzipped [(1, 2, 3), (4, 5, 6)] Neat and completely confusing, huh? :-) http://paddy3118.blogspot.com/2007/02/unzip-un-needed-in-python.html I hadn't thought about zip() being symmetrical like that. Very cool... Rich -- http://mail.python.org/mailman/listinfo/python-list
Re: Descriptors and side effects
[EMAIL PROTECTED] wrote: Hello everyone, I'm trying to do seemingly trivial thing with descriptors: have another attribute updated on dot access in object defined using descriptors. [snip] A setter function should have updated self.l just like it updated self.s: def __set__(self, obj, val): self.s=val self.l=len(val) print setting value:, self.s, length:, self.l Yet it didn't happen. [snip] I noticed that Python will block all attribute overrides (either via __dict__ through setattr) if the property has a __set__ method. The standard property has this method and there is no way that I can find to defeat it. So, here is what I use: class ConstProperty(object): Provides a property that keeps its return value. The function will only be called on the first access. After that the same value can be used over and over again with no function call penalty. If the cached value needs to be cleared, simply del the attribute. class MyClass(object): ... def __init__(self, x): ... self.x = x ... @ConstProperty ... def y(self): ... print HERE ... return self.x ** 2 ... obj = MyClass(5) obj.y HERE 25 obj.y 25 def __init__(self, fn): self.fn = fn def __get__(self, target, cls=None): if target is None: return self.fn # Helps pydoc else: obj = self.fn(target) setattr(target, self.fn.__name__, obj) return obj This is a little different than what you originally posted, but hopefully it is close enough to be helpful. Cheers! Rich -- http://mail.python.org/mailman/listinfo/python-list
Re: Descriptors and side effects
Bruno Desthuilliers wrote: [snip] I'm sorry, but this looks like a very complicated way to do a simple thing: class MySimpleClass(object): def __init__(self, x): self.x = x self.y = x ** 2 Sure, for the absurdly simplified case I posed as an example. ;) Here's another: class Path(tuple): @ConstProperty def pathstr(self): print DEBUG: Generating string return '/'.join(self) def __add__(self, other): if isinstance(other, tuple): return Path(tuple.__add__(self, other)) else: return Path(tuple.__add__(self, (other,))) ROOT = Path(()) path = ROOT + 'x' + 'y' + 'z' path.pathstr DEBUG: Generating string /x/y/z path.pathstr /x/y/z Basically, you can use ConstProperty above for items you don't want to calculate automatically, but only when someone actually WANTS it. After it is applied, then the penalties for function call of the property and the computation are wiped out once the second access is requested. Now, in the original example, len() might be considered too little for this use and should be just generated in the constructor for free. OTOH, that assumes that __len__ hasn't been overridden to do something more complicated and time consuming. If the antecedent object is static, and the derivative consequent is also static, then ConstProperty works very well and shouldn't cost more on the first access than any other built-in property function. BTW, another use is to avoid creating lots of unnecessary objects for free unless they are accessed. Another quickie example: class Node(object): hasChildList = False hasAttributesDict = False @ConstProperty def children(self): self.hasChildList = True return [] @ConstProperty def attributes(self): self.hasAttributesDict = True return {} The extra class/object attributes can be used to test for whether the associated objects were created. When used in a large tree, not creating a lot of extra lists and dictionaries can save a lot of memory and CPU as the children and attributes are not created or explored unless they were manipulated. Rich -- http://mail.python.org/mailman/listinfo/python-list
Re: Descriptors and side effects
Bruno Desthuilliers wrote: Rich Harkins a écrit : [EMAIL PROTECTED] wrote: Hello everyone, I'm trying to do seemingly trivial thing with descriptors: have another attribute updated on dot access in object defined using descriptors. [snip] A setter function should have updated self.l just like it updated self.s: def __set__(self, obj, val): self.s=val self.l=len(val) print setting value:, self.s, length:, self.l Yet it didn't happen. [snip] I noticed that Python will block all attribute overrides (either via __dict__ through setattr) if the property has a __set__ method. It doesn't block, it controls access to... Of course, if the __set__ method is a no-op, then nothing will happen. The standard property has this method and there is no way that I can find to defeat it. defeat ? Why don't you just pass the appropriate fset function to property ? So, here is what I use: class ConstProperty(object): Provides a property that keeps its return value. The function will only be called on the first access. After that the same value can be used over and over again with no function call penalty. If the cached value needs to be cleared, simply del the attribute. class MyClass(object): ... def __init__(self, x): ... self.x = x ... @ConstProperty ... def y(self): ... print HERE ... return self.x ** 2 ... obj = MyClass(5) obj.y HERE 25 obj.y 25 def __init__(self, fn): self.fn = fn def __get__(self, target, cls=None): if target is None: return self.fn # Helps pydoc else: obj = self.fn(target) setattr(target, self.fn.__name__, obj) return obj m = MyClass(5) m.__dict__ {'x': 5} m.y HERE 25 m.__dict__ {'y': 25, 'x': 5} m.x = 42 m.y 25 m.__dict__ {'y': 25, 'x': 42} I'm sorry, but this looks like a very complicated way to do a simple thing: class MySimpleClass(object): def __init__(self, x): self.x = x self.y = x ** 2 -- http://mail.python.org/mailman/listinfo/python-list
Re: Functions as Objects, and persisting values
[snip] The thing you observe here is a called a closure. It consists of the local variables surrounding e. So as long as you keep a reference to e, you keep one to the variables of d itself. Diez More specifically though it keeps references to the requested variables only: def closed(): x = global_x y = Y_VAR def inner(): return y return inner class Destroyable(object): def __del__(self): print DESTROYED global_x = Destroyable() inner = closed() print inner() del global_x print inner() print HERE You will get: Y_VAR DESTROYED Y_VAR HERE If the entire dict of closed() was kept you would have seen: Y_VAR Y_VAR HERE DESTROYED Since closed hadn't been destroyed yet: thus there was only one reference remaining to global_x after closed() and inner() were called. Rich -- http://mail.python.org/mailman/listinfo/python-list
Re: Descriptors and side effects
Bruno Desthuilliers wrote: Which is easy to do with properties too. True enough. It's the caching of the return value that's the value add of course. ;) After it is applied, then the penalties for function call of the property and the computation are wiped out once the second access is requested. Agreed. But I wouldn't use such a scheme for mutable types - which are still the common case. In many cases, yeah. Though I use a lot of immutable stuff in some of my pet projects and such. ConstProperty is definitely not meant as a replacement for property, only when something constant can be derived from something else constant, especially when the derivation is expensive. Now, in the original example, len() might be considered too little for this use and should be just generated in the constructor for free. OTOH, that assumes that __len__ hasn't been overridden to do something more complicated and time consuming. If the antecedent object is static, and the derivative consequent is also static, You mean 'immutable', I assume... Yeah, that's probably the better term. [snip] Again, I've used it quite a bit for various things and it's worked well for the sort of thing the OP was requesting. Of course, your mileage may vary. :) Cheers! Rich PS: Sorry about the weird reposts. Thunderbird chaos. -- http://mail.python.org/mailman/listinfo/python-list