# Lisp mentality vs. Python mentality

bearophileHUGS at lycos.com bearophileHUGS at lycos.com
Sun Apr 26 14:07:25 CEST 2009

```Paul Rubin:
> Arnaud Delobelle:
> > Do you mean imap(comp, a, b)?
>
> Oh yes, I forgot you can do that.  Thanks.

That works and is nice and readable:

import operator
from itertools import imap

def equal_sequences(a, b, comp=operator.eq):
"""
a and b must have __len__

>>> equal_sequences([1, 2, 3], [1, 2, 3])
True
>>> L1, L2 = [1, 2, 3], [1, -2, 3]
>>> equal_sequences(L1, L2)
False
>>> equal_sequences(L1, L2, lambda x,y: abs(x) == abs(y))
True
>>> L3, L4 = ["hello", "HALLO"], ["hello", "hallo"]
>>> equal_sequences(L3, L4)
False
>>> equal_sequences(L3, L4, lambda x,y: x.lower() == y.lower())
True
"""
return len(a) == len(b) and all(imap(comp, a, b))

if __name__ == "__main__":
import doctest
doctest.testmod()
print "Doctests finished.\n"

But both sequences must have a len. Otherwise you may use (if you
don't have izip_longest the folllowing code gets longer):

"""
>>> equal_items([1, 2], [1, 2, 3])
False
>>> equal_items([1, 2, 3], [1, 2, 3])
True
>>> equal_items([1, 2, 3], [1, -2, 3])
False
>>> equal_items([1, 2, 3], [1, -2, 3], abs)
True
>>> equal_items([1, 2, 3], [1, -2, 4], abs)
False
>>> L1, L2 = ["hello", "HALLO"], ["hello", "hallo"]
>>> equal_items(L1, L2)
False
>>> equal_items(L1, L2, str.lower)
True
>>> equal_items(xrange(3), (i for i in xrange(3)))
True
>>> equal_items([0, 1, 2], (i for i in xrange(3)))
True
>>> equal_items([0, 1, 2, 3], (i for i in xrange(3)))
False
>>> equal_items([-0, -1, -2], (i for i in xrange(3)), key=abs)
True
>>> equal_items([-0, -1, -2, -3], (i for i in xrange(3)), key=abs)
False
>>> x = []
>>> equal_items( (x for i in range(3)), (x for i in range(3)) )
True
>>> equal_items( (x for i in range(3)), (x for i in range(4)) )
False
>>> equal_items( (x for i in range(3)), (x for i in range(3)), key=id)
True
>>> equal_items( (x for i in range(3)), (x for i in range(4)), key=id)
False
>>> equal_items( (x for i in range(3)), (x for i in range(3)), key=lambda x:x)
True
>>> equal_items( (x for i in range(3)), (x for i in range(4)), key=lambda x:x)
False
"""

from itertools import izip_longest

def equal_items(iter1, iter2, key=None):
try:
len_iter1 = len(iter1)
len_iter2 = len(iter2)
except TypeError:
pass
else:
if len_iter1 != len_iter2:
return False

class Guard(object): pass

if key is None:
for x, y in izip_longest(iter1, iter2, fillvalue=Guard()):
if x != y:
return False
else:
try:
for x, y in izip_longest(iter1, iter2, fillvalue=Guard()):
if key(x) != key(y):
return False
except TypeError: # intercepts key(guard)
return False

return True

if __name__ == "__main__":
import doctest
doctest.testmod()
print "Doctests finished.\n"

You can write hairy code in Python too, not just in CLisp :-)

Bye,
bearophile

```