Posts Tagged python

Python generator to list decorator

Python generators can be evil because of the implicit state. How many time have you written done this?

items = get_items()
print items
f(items, x)

It might prevent confusion if generators are only used when you need lazy iteration.

However, creating a list, appending to it several times and then returning it is an effort – which is probably why I want to use generators when I don’t need to.

One workaround is to create a python generator to list decorator like so

def listify(gen):
    "Convert a generator into a function which returns a list"
    def patched(*args, **kwargs):
        return list(gen(*args, **kwargs))
    return patched

@listify
def f(x):
     for i in range(x):
        yield "item" + str(i)

assert f(5) == "item0 item1 item2 item3 item4".split()

One can also define a dictate decorator as follows

from functools import wraps

def dictate(func):
    @wraps(func)
    def patched(*args, **kwargs):
        return dict(*func(*args, **kwargs))
    return patched

Add comment March 29, 2009

Getting python argspecs

For the benefit of google:

def f(x, *args, **kwargs):
    return x
import inspect
print inspect.getargspec(f)

Add comment March 22, 2009

Human string comparison in python

NOTE: An alternative way to do this

I’ve found a possible alternative to this. If you only want to sort strings in your current locale you can use locale.strcoll, which is a cmp function in your current locale.

import locale
["one", "two", "three"].sort(locale.strcoll)
l

On my machine this still isn’t a very human friendly sort but depending on your LC_COLLATE environment variable it may be. This is very much less of a reinvent-the-wheel-because-buying-one-is-too-hard approach – though I suspect it might take one 4 times as long to get working…

Of course at times what you want your commadline to do isn’t what you want all other programs to do…


The string comparison in python does not order lists as one would expect:

>>> l.sort(weird_strcmp)
>>> l
['hello', '?', '}']
>>> l = ["1", "Hello", "abc", "?", "}"]
>>> l.sort()
>>> l
['1', '?', 'Hello', 'abc', '}']
>>>

python sorts strings as sequences of bytes.

I couldn’t find any easy way to sort strings in a more friendly fashion (Though surely one must exist?!) So here is an quick implementation of one (use this code as you wish):

from itertools import chain

letters = list(chain(*zip(range(0x41, 0x41 + 26),
               range(0x61, 0x61 + 26)))) # interspersed upper and lower

numbers = range(0x30, 0x30 + 10)

symbols = sorted(list(
        set(range(0x80)) - set(letters) - set(numbers)))

weird_order = list(chain(letters, numbers, symbols))

assert set(weird_order) == set(range(0x80)), "Didn't get every character"

def weird_strcmp(a, b):
    """Compare strings for lists for English humans who hate
         unicode and aren't using python 3k any time soon."""

    a = map(ord, a)
    b = map(ord, b)

    for x in chain(a, b):
        assert x < 0x80, "%s is not in the ascii character range" % x

    a = map(weird_order.index, a)
    b = map(weird_order.index, b)
    return cmp(a, b)
>>> l.sort(weird_strcmp)
>>> l
['abc', 'Hello', '1', '?', '}']

Be aware that this isn’t really tested and may not order symbols how you think they should be. It, however, has the advantage of not taking you 15-30 minutes to write and debug. Say if you can think of any foibles and I’ll fix them.

Add comment March 18, 2009

A python caching decorator for referential transparent functions

The following is quite a nice way of automating caching in python functions using decorators. This code will work whenever a function depends on only its paramters (this is called referential transparency.)

def cached(func):
    cache = {}
    def new_func(*args):
        if args in cache:
             return cache[args]
        else:
             temp = cache[args] = func(*args)
             return temp
    return new_func

def non_cachedFunc(blah)
    ....blah

@cached
def cacheFunc(blah):
    ...blah

This makes turning caching on and off very easy and saves quite a lot of typing. The only overhead added to each call to a cached function should be one extra function call and a dictionary membership test.

Add comment March 12, 2008


Meta

Facets

abstruse Add new tag AOP apt aspect oriented programming assumes knowledge autiobiographical bash scripts bell books clarity code samples configuration console emacs for the benefit of google functional programming graphical design hacks higher-order functions howtos intention revealing programming keyboard links linux note to self opinions parsing patterns philosophising philosophizing programming python random ideas refactoring removing packages short stories succinct svn systems stuff theoretical philosophizing typing work ethic you probably don't want to read this

Archives

Pages

 

November 2009
M T W T F S S
« Aug    
 1
2345678
9101112131415
16171819202122
23242526272829
30