On Wed, Dec 14, 2011 at 6:15 PM, Bert Freudenberg <b...@freudenbergs.de>wrote:
> On 14.12.2011, at 22:42, Vernon Cole wrote: > > > Sorry, Kirby, I'm afraid I disagree. > > try: > > res_dict[ext] += 1 > > except KeyError: > > res_dict[ext] = 1 > > is clear in intent and operation. It is a self-initializing occurrence > counter. > > > > On the other hand, > > res_dict[ext] = res_dict.get(ext, 0) + 1 > > is obscure. > SNIP > Isn't this at least as readable, and conceptually simpler? > > if ext in res_dict: > res_dict[ext] += 1 > else: > res_dict[ext] = 1 > > Not arguing against exceptions in general, but in this case? > > Personally, I find both the if/else and the try/except much easier to remember, and slightly easier to read than the one-liner. Furthermore, if one is interested in performance, it appears that the if/else approach is *always* faster than the one-liner. When exceptions are rarely raised, then the try/except approach is the fastest. Below are the results from a quick test to compare the efficiency of the three cases, followed by the code. This is using Python 2.7 on a fairly old computer. André =============================== 100% new keys setdefault: 0.532404899597 try/except: 2.029556036 if/else: 0.241212844849 -------------------------------------------------- 10% new keys setdefault: 0.621008872986 try/except: 0.585212945938 if/else: 0.32776093483 -------------------------------------------------- 1% new keys setdefault: 0.615134000778 try/except: 0.388912916183 if/else: 0.321834087372 -------------------------------------------------- 0.1% new keys setdefault: 0.527935028076 try/except: 0.28360915184 if/else: 0.334416866302 ================ from timeit import Timer print "100% new keys\n" print 'setdefault:\t', t = Timer(""" d = {} for i in range(1000): d[i] = d.get(i, 0) + 1 """) print t.timeit(number=1000) print 'try/except:\t', t = Timer(""" d = {} for i in range(1000): try: d[i] += 1 except KeyError: d[i] = 1 """) print t.timeit(number=1000) print 'if/else:\t', t = Timer(""" d = {} for i in range(1000): if i in d: d[i] += 1 else: d[i] = 1 """) print t.timeit(number=1000) print "-"*50 print "10% new keys" print 'setdefault:\t', t = Timer(""" d = {} for i in range(1000): k = i % 100 d[k] = d.get(k, 0) + 1 """) print t.timeit(number=1000) print 'try/except:\t', t = Timer(""" d = {} for i in range(1000): k = i % 100 try: d[k] += 1 except KeyError: d[k] = 1 """) print t.timeit(number=1000) print 'if/else:\t', t = Timer(""" d = {} for i in range(1000): k = i % 100 if i in d: d[k] += 1 else: d[k] = 1 """) print t.timeit(number=1000) print "-"*50 print "1% new keys\n" print 'setdefault:\t', t = Timer(""" d = {} for i in range(1000): k = i % 10 d[k] = d.get(k, 0) + 1 """) print t.timeit(number=1000) print 'try/except:\t', t = Timer(""" d = {} for i in range(1000): k = i % 10 try: d[k] += 1 except KeyError: d[k] = 1 """) print t.timeit(number=1000) print 'if/else:\t', t = Timer(""" d = {} for i in range(1000): k = i % 10 if i in d: d[k] += 1 else: d[k] = 1 """) print t.timeit(number=1000) print "-"*50 print "0.1% new keys\n" print 'setdefault:\t', t = Timer(""" d = {} for i in range(1000): d[1] = d.get(1, 0) + 1 """) print t.timeit(number=1000) print 'try/except:\t', t = Timer(""" d = {} for i in range(1000): try: d[1] += 1 except KeyError: d[1] = 1 """) print t.timeit(number=1000) print 'if/else:\t', t = Timer(""" d = {} for i in range(1000): if 1 in d: d[1] += 1 else: d[1] = 1 """) print t.timeit(number=1000)
_______________________________________________ Edu-sig mailing list Edu-sig@python.org http://mail.python.org/mailman/listinfo/edu-sig