News for hackers. Stuff that matters.
Re:A Hodgepodge of Python by lysium on Thursday September 15, 2011 @05:15PM (#3002164)
Didn't know the timeit module. However, the presented usage to time list reversing is ill: The timing is dominated by the list creation, which should go into setup. Then I'll get:

    $ 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.
Re:A Hodgepodge of Python by Sharlin on Thursday September 15, 2011 @05:40PM (#3002235)

  >>> 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.
Re:A Hodgepodge of Python by akx on Friday September 16, 2011 @06:17AM (#3003886)
And more often than not `xrange` is what one needs, not `range`. (Not relevant with Py3k though, but everyone is still in 2.x-verse.)
Re:A Hodgepodge of Python by lysium on Friday September 16, 2011 @08:09AM (#3004115)

    >>> xrange(13)[::-1]
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: sequence index must be integer, not 'slice'
Re:A Hodgepodge of Python by akx on Friday September 16, 2011 @09:15AM (#3004295)

  >>> list(range(13)[::-1]) == list(xrange(12, -1, -1))
  True
Re:A Hodgepodge of Python by lysium on Friday September 16, 2011 @08:08AM (#3004112)
True: $ python -mtimeit -s'l=range(1000)' 'a=[i for i in reversed(l)]' 10000 loops, best of 3: 37.7 usec per loop
Re:A Hodgepodge of Python by balbeit on Thursday September 15, 2011 @05:48PM (#3002257)
I always love learning little tidbits about Python like these. Thanks!

Another 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.
Re:A Hodgepodge of Python by randlet on Thursday September 15, 2011 @09:01PM (#3002714)
You can use the Counter class from the collections module[1] for that as well.

  >>> 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...
Re:A Hodgepodge of Python by BrandonM on Thursday September 15, 2011 @09:01PM (#3002712)
get() doesn't create a value in the dictionary, though; it only returns a default value. For what you describe, you would want setdefault(). It works here because you're assigning a value to a['foo'] after get()ing the default value.
Re:A Hodgepodge of Python by BrandonM on Thursday September 15, 2011 @09:11PM (#3002740)
I use defaultdict a lot. It's useful not only for counters, but also for sets, lists, dicts, and even other defaultdicts. It usually results in very succinct code compared to alternatives:

  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.)
Re:A Hodgepodge of Python by notaddicted on Thursday September 15, 2011 @05:17PM (#3002171)
I'm still on the fence as to whether this is acceptably ugly or unacceptably ugly, but it does make use of a python feature:

  >>> 
  >>> 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}
  >>>
Re:A Hodgepodge of Python by Estragon on Thursday September 15, 2011 @07:32PM (#3002523)
The main question is whether it increases the clarity and flexibility of the code. I can't think of any contexts where it would, but I wouldn't rule it out.
Re:A Hodgepodge of Python by gbog on Friday September 16, 2011 @01:15AM (#3003282)
The more I use Python the more I like it. It allows a lot of the early refactorings needed for a proof of concept prototype. Playing with it feels like playing with a well lubrificated rubix cube, it rotates well in all directions, allowing quick changes in the code's structure. I can't tell exactly why but I think the use of "self" in object methods, while a bit weird in the begining, is one of the best part. Eg morphing a helper function into a method is just a matter of one search and replace.
Re:A Hodgepodge of Python by ashrust on Thursday September 15, 2011 @08:57PM (#3002701)
This is the stuff that brings me back to hacker news everyday. So helpful.
Re:A Hodgepodge of Python by mumrah on Thursday September 15, 2011 @09:40PM (#3002815)
izip is the super useful generator counterpart of zip

Also, 2.7 introduced a couple of cool things in collections: OrderedDict and Counter

Re:A Hodgepodge of Python by skrebbel on Friday September 16, 2011 @03:48AM (#3003565)
> In my mind, dynamic typing = bugs, interpreted language = slow. Ahhhhh!

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.

Re:A Hodgepodge of Python by grantjgordon on Friday September 16, 2011 @02:26AM (#3003393)
Thanks for posting these tips!