Lisp mentality vs. Python mentality
Arnaud Delobelle
arnodel at googlemail.com
Sun Apr 26 04:05:25 EDT 2009
namekuseijin <namekuseijin.nospam at gmail.com> writes:
> Ciprian Dorin, Craciun wrote:
>> On Sun, Apr 26, 2009 at 7:54 AM, Steven D'Aprano
>> <steve at remove-this-cybersource.com.au> wrote:
>> I liked very much your implementation for the compare function, it
>> is very short and at the same time readable:
>>
>>> def compare(a, b, comp=operator.eq):
>>> return (len(a) == len(b)) and all(comp(*t) for t in zip(a, b))
>>
>> But I have only one problem, it is suboptimal, in the sense that:
>> * it constructs two intermediary lists (the list comprehension and
>> the zip call);
No, it only constructs one list (the zip() one) and only in Python 2.x -
in Python 3.x, zip return a special 'zip object'. There is no list
comprehension. It's a generator expression [1].
To avoid the list created by zip in python 2.x (for x large enough!),
just do:
from itertools import izip as zip
Another way to define the function that may appeal to you, as a lisper.
def compare(a, b, comp=operator.eq):
return len(a) == len(b) and all(map(comp, a, b))
The same remark applies to map() here as to zip() above.
>
>> * it evaluates all the elements, even if one is false at the beginning;
It does not [2].
> This evaluates just until finding one that is false:
>
> return (len(a) == len(b)) and not any(not comp(*t) for t in
> (zip(a, b)))
>
> plus the zip call enclosed in parentheses got turned into an iterator.
not any(not i for i in iterable) is not an optimisation of
all(iterable). Refer to [2]. Moreover, putting a list in parenthesis
does not magically turn it into a generator.
--
Arnaud
[1] http://www.python.org/dev/peps/pep-0289/
[2] http://docs.python.org/library/functions.html
More information about the Python-list
mailing list