Welcome, guest | Sign In | My Account | Store | Cart

While the find() and count() string functions can check for string occurences, there is no function to check on the occurence of a set of characters.

Python, 15 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
def containsAny(str, set):
    """Check whether 'str' contains ANY of the chars in 'set'"""
    return 1 in [c in str for c in set]

def containsAll(str, set):
    """Check whether 'str' contains ALL of the chars in 'set'"""
    return 0 not in [c in str for c in set]

if __name__ == "__main__":
    # unit tests, must print "OK!" when run
    assert containsAny('*.py', '*?[]')
    assert not containsAny('file.txt', '*?[]')
    assert containsAll('43221', '123')
    assert not containsAll('134', '123')
    print "OK!"

While working on a condition to check whether a string contained the special characters used in the glob.glob() standard library function, I came up with the above code (with help from the OpenProjects IRC channel #python). Written this way, it really is compatible with human thinking, even though you might not come up with such code intuitively. That is often the case with list comprehensions.

"[c in str for c in set]" creates a list of true/false values, one for each char in the set. "1 in [c in str for c in set]" then checks if at least one "true" is in that list.

Similarly, "0 not in truthlist" checks that no "false" is in the list, i.e. that all conditions are true.

2 comments

Hamish Lawson 22 years, 9 months ago  # | flag

Neat idiom. A very neat idiom and a good illustration of the power of list comprehensions.

Horst Hansen 22 years, 9 months ago  # | flag

Another solution. It might be a neat idiom, but i prefer the following solution, because:

a) It reads almost as plain English and I think this is always more Pythonic :)

b) It is definitely more efficient. You can break out of the loop early via return after the first matching character is found (containsAny case) and after the first character in 'set' is found that is not contained in 'str' (containsAll case).

def my_containsAny(str, set):
    for c in set:
        if c in str: return 1;
    return 0;


def my_containsAll(str, set):
    for c in set:
        if c not in str: return 0;
    return 1;
Created by Jürgen Hermann on Fri, 29 Jun 2001 (PSF)
Python recipes (4591)
Jürgen Hermann's recipes (14)
Python Cookbook Edition 2 (117)
Python Cookbook Edition 1 (103)

Required Modules

  • (none specified)

Other Information and Tasks