On Mar 29, 4:19 pm, Steven D'Aprano <st...@remove-this- cybersource.com.au> wrote: > On Mon, 29 Mar 2010 07:40:54 -0700, Patrick Maupin wrote: > > On Mar 28, 9:45 pm, Steven D'Aprano > > <ste...@remove.this.cybersource.com.au> wrote: > >> And what about tuples? And subclasses of list/tuples? How many > >> different types need to be optimized? > > > One of the beautiful things about Python is that, for most things, there > > are few surprises for even new users. "There should be one obvious way > > to do it" for the user means that, sometimes, under the hood, there are > > a lot of special cases for the implementers. > > It never ceases to amaze me how often people simply don't understand this. > > "There should be one obvious way to do it" is the opposite of "NO obvious > way", not of "many ways which may or may not be obvious". The complete > quote from the Zen makes that clear: > > There should be one-- and preferably ONLY one --obvious way to do it. > [Emphasis added] > > And don't forget the next line: > > Although that way may not be obvious at first unless you're Dutch. > > Python is under no compulsion to make "the obvious way" obvious to anyone > except Guido. It's a bonus if it happens to be obvious to newbies, not a > requirement. > > And besides, what is "it" you're talking about? > > * Adding integers, decimals or fractions, or floats with a low > requirement for precision and accuracy? Use sum. > > * Adding floats with a high requirement for precision and accuracy? > Use math.fsum. > > * Concatenating strings? Use ''.join. > > * Joining lists? Use [].extend. > > * Iterating over an arbitrary sequence of arbitrary sequences? > Use itertools.chain. > > That's five different "its", and five obvious ways to do them. >
Let's go through them... > * Adding integers, decimals or fractions, or floats with a low > requirement for precision and accuracy? Use sum. > Pretty obvious. >>> sum([1, 2, 3]) 6 > * Adding floats with a high requirement for precision and accuracy? > Use math.fsum. > Mostly obvious. >>> fsum([1.234534665989, 2.987, 3]) Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'fsum' is not defined >>> import math >>> math.fsum([1.234534665989, 2.987, 3]) 7.2215346659890001 > * Concatenating strings? Use ''.join. Common pitfall: >>> ['abc', 'def', 'ghi'].join() Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'list' object has no attribute 'join' >>> ''.join(['abc', 'def', 'ghi']) 'abcdefghi' > * Joining lists? Use [].extend. Obvious, yes. Convenient? Not really. >>> start = [] >>> for list in [[1, 2], [3, 4]]: ... start.extend(list) ... >>> start [1, 2, 3, 4] > * Iterating over an arbitrary sequence of arbitrary sequences? > Use itertools.chain. >>> group1 = ['al', 'bob'] >>> group2 = ['cal'] >>> groups = [group1, group2] Obvious if you are Dutch... >>> itertools.chain(groups) Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'itertools' is not defined >>> import itertools >>> itertools.chain(groups) <itertools.chain object at 0x9a9658c> >>> len(itertools.chain(groups)) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: object of type 'itertools.chain' has no len() >>> len(list(itertools.chain(groups))) 2 >>> len(list(itertools.chain(*groups))) 3 So you have sum, fsum, join, extend, and chain. Sum is builtin, but you have to import fsum from math and chain from itertools. Join is actually a method on strings, not sequences. Chain can take multiple lists, or you can use the splat operator on a list of lists. Extend is actually a method on lists, and it only takes one list, not multiple ones. >>> [].extend(*groups) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: extend() takes exactly one argument (2 given) Just commit all that to memory, and enjoy the productivity of using a high level language! ;) -- http://mail.python.org/mailman/listinfo/python-list