andmap and ormap

W

wkehowski

Hello,

Does python have andmap and ormap:

andmap((lambda t: boolean(t)),L)

gives True if boolean(t) is True for all t in L and False otherwise?
And

ormap((lambda t: boolean(t)),L)

gives True if boolean(t) is True for some t in L and False otherwise?
One can use a list comprehension like

[x for x in L if not(False in map((lambda t: boolean(t)),L))]

as an example of selection by andmap, and

[x for x in L if (True in map((lambda t: boolean(t)),L))]

as an example of selection by ormap.

How does one define andmap/ormap so its first argument is a boolean
procedure or lambda?

def andmap(b,L):
if False in map(b,L): return False
else: return True

def ormap(b,L):
if True in map(b,L): return True
else: return False

Is this good enough?

Walter Kehowski
 
F

Felipe Almeida Lessa

Em Ter, 2006-03-14 às 04:23 -0800, (e-mail address removed) escreveu:
def andmap(b,L):
if False in map(b,L): return False
else: return True

def ormap(b,L):
if True in map(b,L): return True
else: return False

Is this good enough?

The problem is that it will evaluate all possibilities needlessly. Try
(not tested and 2.4-only):

def andmap(func, objs):
for boolean in (func(obj) for obj in objs):
if not boolean:
return False
return True

def ormap(func, objs):
for boolean in (func(obj) for obj in objs):
if boolean:
return True
return False

--
"Quem excele em empregar a força militar subjulga os exércitos dos
outros povos sem travar batalha, toma cidades fortificadas dos outros
povos sem as atacar e destrói os estados dos outros povos sem lutas
prolongadas. Deve lutar sob o Céu com o propósito primordial da
'preservação'. Desse modo suas armas não se embotarão, e os ganhos
poderão ser preservados. Essa é a estratégia para planejar ofensivas."

-- Sun Tzu, em "A arte da guerra"
 
D

Dan Sommers

On 14 Mar 2006 04:23:55 -0800,
Hello,
Does python have andmap and ormap:
andmap((lambda t: boolean(t)),L)
gives True if boolean(t) is True for all t in L and False otherwise?
And
ormap((lambda t: boolean(t)),L)
gives True if boolean(t) is True for some t in L and False otherwise?

import operator
reduce( L, operator.and_ ) # andmap
reduce( L, operator.or_ ) # ormap
One can use a list comprehension like

[ ... ]
Is this good enough?

If it works, and works correctly, then it's good enough.

Regards,
Dan
 
D

Diez B. Roggisch

Does python have andmap and ormap:
andmap((lambda t: boolean(t)),L)

gives True if boolean(t) is True for all t in L and False otherwise?
And

ormap((lambda t: boolean(t)),L)

gives True if boolean(t) is True for some t in L and False otherwise?
One can use a list comprehension like

[x for x in L if not(False in map((lambda t: boolean(t)),L))]

as an example of selection by andmap, and

[x for x in L if (True in map((lambda t: boolean(t)),L))]

as an example of selection by ormap.

How does one define andmap/ormap so its first argument is a boolean
procedure or lambda?

def andmap(b,L):
if False in map(b,L): return False
else: return True

def ormap(b,L):
if True in map(b,L): return True
else: return False


import operator

reduce(operator.and_, [predcidate(o) for o in objects])

predicate can be a lambda, if it has to be.

Diez
 
F

Fredrik Lundh

Felipe said:
The problem is that it will evaluate all possibilities needlessly. Try
(not tested and 2.4-only):

footnote: if you have a recent Python 2.5 build, you can make them even
shorter:
any(...)
any(iterable) -> bool
Return True if bool(x) is True for any x in the iterable.
all(...)
all(iterable) -> bool
Return True if bool(x) is True for all values x in the iterable.

</F>
 
J

Joel Hedlund

footnote: if you have a recent Python 2.5 build,

Who would have that? Is it a good idea to use a pre-alpha python version? Or any unrealeased python version for that matter? I was under the impression that the recommended way to go for meager developers in python like myself is to stick with the latest stable production release (2.4.2 at the time of writing I believe). Or should I start grabbing the Subversion trunk on a nightly basis?

Cheers!
/Joel Hedlund
 
P

Peter Otten

def ormap(b,L):
if True in map(b,L): return True
else: return False

Is this good enough?

No, because

- (as Felipe observed) it doesn't shortcut, i. e. it always evaluates
b(item) for all items in L.
- it creates a temporary list
- if truthvalue: return True
else: return False
is redundant and just plain ugly

Just write

return truthvalue

or, when truthvalue may consume a lot of memory,

return bool(truthvalue) # or: return not not truthvalue

Which gives:

def andmap(predicate, items):
return False not in (predicate(item) for item in items)

def ormap(predicate, items):
return True in (predicate(items) for item in items)

andmap((lambda t: boolean(t)),L)

Superfluous lambda alert: make that

andmap(boolean, L)

Python 2.5 will feature similar functions any() and all() which seem to have
a fixed predicate == bool, though.

Peter
 
G

Georg Brandl

Joel said:
Who would have that? Is it a good idea to use a pre-alpha python version?
Or any unrealeased python version for that matter? I was under the impression that
the recommended way to go for meager developers in python like myself is to stick
with the latest stable production release (2.4.2 at the time of writing I believe).
Or should I start grabbing the Subversion trunk on a nightly basis?

As most of the new features 2.5 is going to have are already implemented,
it's quite possible that people do checkout the SVN trunk and play with them.

Course, Fredrik could have said "In 2.5 you'll be able to write..."

Georg
 
G

Georg Brandl

Peter said:
Python 2.5 will feature similar functions any() and all() which seem to have
a fixed predicate == bool, though.

You cannot write

all(predicate, list)

but

all(predicate(x) for x in list)

Georg
 
P

Peter Otten

Peter said:
def ormap(predicate, items):
return True in (predicate(items) for item in items)

should be

def ormap(predicate, items):
return True in (predicate(item) for item in items)

Hmmpf.

Peter
 
W

wkehowski

The following works perfectly:

import operator

def andmap(b,L):
return reduce(operator.and_, [b(x) for x in L])

def ormap(b,L):
return reduce(operator.or_, [b(x) for x in L])

Thanks!
 
T

Terry Reedy

Joel Hedlund said:
Who would have that? Is it a good idea to use a pre-alpha python version?

The pre-public release version compiles as 'alpha0'. I have the impression
the current alpha0 is being kept closer to releaseable more of the time
than used to be the case. For instance, the developers recently set up a
buildbot system to compile and run all unit tests on several systems with a
variety of hardware and OSes up to several times a day. The results are
available at
http://www.python.org/dev/buildbot/

At of minutes ago, 5 systems are green (ok), 1 orange (warn) , and 1 red
(fail).
... Or should I start grabbing the Subversion trunk on a nightly basis?

'Should' if you want to experiment with new features or test existing code
now rather than later. I would only grab it when the tests pass on the
system closest to yours, and only repeat when there is a reason to.

Terry Jan Reedy
 
S

Scott David Daniels

The following works perfectly:
import operator
def andmap(b,L):
return reduce(operator.and_, [b(x) for x in L])
def ormap(b,L):
return reduce(operator.or_, [b(x) for x in L])

Note your [b(x) for x in L] evaluates b(x) for all elements of L
before you begin the analysis.
In 2.3 and beyond, you could define:

def imap(function, source):
for element in source:
yield function(element)

And apply any or all (as defined below) to imap(b, L)

Although, you often needn't use bool(expr) in Python, more things are
reasonable to use directly as tests; if implicitly converts to bool.
So, for those cases, you could simply use any(L) or all(L).

If you wish to use any and all (coming in 2.5), you could go with:

def any(iterable):
'''True iff at least one element of the iterable is True'''
for element in iterable:
if element:
return True # or element and change the definition
return False

def all(iterable):
'''True iff no element of the iterable is True'''
for element in iterable:
if not element:
return False
return True

These will short-circuit in 2.3 and up (where iterators live).
In 2.4 and up, generator expressions can be used:

any(x*7-4 > 100 for x in xrange(50))

Even in 2.3, any and all as defined above work with generators:

def generates(limit):
for i in xrange(limit):
yield i * 7 - 4 > 100

any(generates(800000000))
True
any(generates(8))
False

--Scott David Daniels
(e-mail address removed)
 
P

Peter Otten

Peter said:
def andmap(predicate, items):
    return False not in (predicate(item) for item in items)
        
def ormap(predicate, items):
    return True in (predicate(items) for item in items)

These are both broken because they imply the test (in e. g. ormap)

if True == predicate(item): ... where if predicate(item): ...

would be appropriate. Sorry for the garbage post.

Follow Felipe's or Scott's recipes.

Peter
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top