asking
Steven D'Aprano
steve+comp.lang.python at pearwood.info
Wed Aug 22 09:56:00 EDT 2012
On Wed, 22 Aug 2012 02:42:16 -0700, alex23 wrote:
> On 08/22/2012 03:17 AM, mingqiang hu wrote:
>> I mean any of "a","b","c" in string "adfbdfc" makes the statement
>> true,can I not use a function?
>
> any(map(string.__contains__, substrings))
Nice.
However, be aware that in Python 2, map() is eager and produces a full
list ahead of time. In Python 3, map() is lazy and only produces results
as needed. Since any returns as soon as it sees a true value, Python 3
can be significantly faster here under some circumstances. For example,
consider:
string = "a"*10000000
substrings = "abcdefghijklmnopqrstuvwxyz"
map(string.__contains__, substrings) in Python 2 produces a list of 26
values:
[True, False, False, False, False, ..., False]
up front, before passing that list to any() which stops as soon as it
sees the first value. Generating those 25 False values was a waste of
time.
In Python 3, map() produces a lazy iterator object that doesn't calculate
the values until required. So map(string.__contains__, substrings)
doesn't do anything straight away. It waits for any() to request a value,
then returns True. any() then immediately returns, and the other 25 False
values never get calculated.
In Python 2, you can use itertools.imap for a lazy version. In Python 3,
you can use list(map( ... )) for an eager version.
Here is a version which is lazy in both Python 2 and 3. I expect it to be
more or less equally as efficient, and I find it easier to read:
any(sub in string for sub in substrings)
There's also an all() function that works similarly to any(), except that
it stops as soon as it sees a false value.
--
Steven
More information about the Python-list
mailing list