tkbx
tkbx

Reputation: 16285

If string can be composed of certain characters?

I'd like to determine if a string can be created using only characters in a list. For example,

>>>acceptableChars = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
>>>print isAcceptable("abc")
True
>>>print isAcceptable("xyz")
False

Upvotes: 0

Views: 661

Answers (6)

kindall
kindall

Reputation: 184270

def isAcceptable(text, acceptableChars=set("abcdefghi")):
    return all(char in acceptableChars for char in text)

Upvotes: 2

abarnert
abarnert

Reputation: 365915

Since your actual use case is:

I'm using this to check if something is a hash (0-9, a-f), so any number of duplicates would be acceptable

How about this:

intvalue = int(possiblehash, 16)

If this succeeds, that means it was a valid hex string—and you have the value, in case you need it. If it raises an exception, it wasn't a valid hex string. So:

try:
   intvalue = int(possiblehash, 16)
except Exception as e:
   print("That's not a hex string! Python says " + str(e))

If you want to use a different means to convert the hex string into some appropriate form instead of an integer, the exact same idea will apply:

try:
    binvalue = binascii.unhexlify(possiblehash)
except Exception as e:
   print("That's not a hex string! Python says " + str(e))

Upvotes: 3

cHao
cHao

Reputation: 86535

Easiest way i can think of: check whether yourString.strip('all your acceptable chars') returns you a blank string.

def isAcceptable(text, acceptable='abcdefghi'):
    return text.strip(acceptable) == ''

If the strip returns '', then the only chars in text were in acceptable as well.

Upvotes: 0

Sam Mussmann
Sam Mussmann

Reputation: 5993

Make a set from acceptableChars:

>>> acceptableChars = set('abcdefghi')

Now we can make isAcceptable check if any of the characters in its argument are not in acceptableChars using set subtraction:

>>> def isAcceptable(s):
    return set(s) <= acceptableChars
>>> isAcceptable("abc")
True
>>> isAcceptable("xyz")
False

Upvotes: 4

inspectorG4dget
inspectorG4dget

Reputation: 114025

In [52]: all(c in acceptableChars and acceptableChars.count(c)==want.count(c) for c in want)
Out[52]: True

In [53]: acceptableChars = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']

In [54]: want = 'abc'

In [55]: all(c in acceptableChars and acceptableChars.count(c)==want.count(c) for c in want)
Out[55]: True

In [56]: want = 'xyz'

In [57]: all(c in acceptableChars and acceptableChars.count(c)==want.count(c) for c in want)
Out[57]: False

Though, the following is a much better way to do this:

def isAcceptable(text, chars):
    store = collections.Counter(chars)
    for char in text:
        if char not in store or not store[char]:
            return False
        store[char] -= 1
    return True

Upvotes: 0

abarnert
abarnert

Reputation: 365915

One possibility is to just loop over the string:

def isAcceptable(s):
    for c in s:
        if not isAcceptableChar(c):
            return False
    return True

It should be pretty obvious how to write the isAcceptableChar function.

Of course if you know a bit more about Python, you'd probably just write:

def isAcceptable(s):
    return all(isAcceptableChar(c) for c in s)

And if you know a bit about set theory, you can probably come up with a more efficient and simpler implementation.

But first get the basic one working, and then think about how to improve it.

Upvotes: 0

Related Questions