A Hodgepodge of Python
blog.adku.com
blog.adku.com
$ python -mtimeit -s'l=range(1000)' 'l[::-1]'
100000 loops, best of 3: 3.05 usec per loop
$ python -mtimeit -s'l=range(1000)' 'l.reverse()'
1000000 loops, best of 3: 0.535 usec per loop
$ python -mtimeit -s'l=range(1000)' 'a=reversed(l)'
1000000 loops, best of 3: 0.39 usec per loop
So, instead of reversing the list in place, creating a new, reversed list seems to be faster. >>> reversed([])
<listreverseiterator object at 0xb73ff7cc>
reversed() does not create a new list, it just returns a reverse-order view of the same list. Of course, often this is exactly what is needed. >>> xrange(13)[::-1]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: sequence index must be integer, not 'slice' >>> list(range(13)[::-1]) == list(xrange(12, -1, -1))
TrueAnother I found quite useful: instead of collections.defaultdict, you can use the dict's get() method to set a default value if the key doesn't exist. get() takes the key and a default value, and if the key doesn't exist it creates one with the default value provided.
a = {}
a['foo'] = a.get('foo',0) + 1
# a = {'foo':1}
a['foo'] = a.get('foo',0) + 1
# a = {'foo':2}
It can be very useful for incrementing keys in a dict, even if they did not exist previously. >>> from collections import Counter
>>> c = Counter()
>>> c['foo']
0
>>> c['bar'] +=1
>>> c['bar']
1
>>>
[1] http://docs.python.org/dev/library/collections.html#collecti... occurrences = defaultdict(int)
digraphs = defaultdict(lambda: defaultdict(int))
prev_ch = None
for ch in long_text:
occurrences[ch] += 1
if prev_ch is not None:
digraphs[prev_ch][ch] += 1
prev_ch = ch
print "Occurrences:"
for ch, count in sorted(occurrences.iteritems()):
print " %s: %i" % (ch, count)
print "Digraph occurences:"
for ch1, counts in sorted(digraphs):
for ch2, count in sorted(counts):
print " %s%s: %i" % (ch1, ch2, count)
(I'm aware that digraphs could be done as a single flat dict; it's just a trivial example to show defaultdict nesting.) >>>
>>> class PrefixStr:
... def __init__(self, prefix):
... self.prefix = prefix
... def __getattr__(self, s):
... return self.prefix+s
...
>>>
>>> q = PrefixStr('xyz_')
>>>
>>> { q.height:11, q.width:7, q.depth:3 }
{'xyz_width': 7, 'xyz_depth': 3, 'xyz_height': 11}
>>>Also, 2.7 introduced a couple of cool things in collections: OrderedDict and Counter
He explained why he changed his mind on performance, but not whether or not "dynamic typing = bugs". This would've been interesting to read about from a recent convert.