'isalnum() in python is testing for True for all strings from a list

Here is a simple code block. I'd like to test each element in the list to see if it contains an Alpha Numeric character for further processing.

#!/usr/bin/python

words = ["cyberpunk" ,"x10", "hacker" , "x15" , "animegirl" , "x20"]
for x in words:
        print x + " / " +  str(x.isalnum())

Unforunately this gives me this output:

cyberpunk / True
x10 / True
hacker / True
x15 / True
animegirl / True
x20 / True

However if I test it as lets say:

x = "x10"
print x.isalnum()
x = "this sucks" 
print x.isalnum()

I get the right result!

True
False

What's the different between the List strings and the standalone strings?



Solution 1:[1]

You seem to think isalnum returns True if a string contains both letters and numbers. What it actually does is return True if the string is only letters or numbers. Your last example contains a space, which is not a letter or number.

You can build up the functionality you want:

words = ["cyberpunk" ,"x10", "hacker" , "x15" , "animegirl" , "x20", "this sucks"]

def hasdigit(word):
    return any(c for c in word if c.isdigit())

def hasalpha(word):
    return any(c for c in word if c.isalpha())

def hasalnum(word):
    return hasdigit(word) and hasalpha(word)

for word in words:
        print word,'/',hasalnum(word)

Output:

cyberpunk / False
x10 / True
hacker / False
x15 / True
animegirl / False
x20 / True
this sucks / False

Solution 2:[2]

Your string that fails contains a space character. None of the entries in the list contains a space.

Solution 3:[3]

Just a discussion as I am suffering from same issue!

According to Python 2.7 Documentation

str.isalnum()
              Return true if all characters in the string are alphanumeric and there is at least one character, false otherwise.

According to Python 3.6.6 Documentation

str.isalnum()
              Return true if all characters in the string are alphanumeric and there is at least one character, false otherwise. A character c is alphanumeric if one of the following returns True: c.isalpha(), c.isdecimal(), c.isdigit(), or c.isnumeric().

Here are few tests for isalnum() in python v3.6.6

>>> "alpha".isalnum()
True
>>> "alpha10".isalnum()
True
>>> "alpha%&@".isalnum()
False
>>> "alpha %&@".isalnum()
False
>>> "alpha with space".isalnum()
False

In first test "alpha".isalnum() returns True

And in isalpha() test, results are like this:

>>> "alpha".isalpha()
True
>>> "alpha10".isalpha()
False
>>> "alpha%&@".isalpha()
False
>>> "alpha %&@".isalpha()
False
>>> "alpha with space".isalpha()
False

So the problem is that isalnum() and isalpha() both returns True when a string contains only characters

>>> "alpha".isalnum()
True
>>> "alpha".isalpha()
True

Results are positive if we combine isalnum() and isalpha() checks to find out alphanumeric on your given list

words = ["cyberpunk" ,"x10", "hacker" , "x15" , "animegirl" , "x20"]
for s in words:
    if s.isalpha() and s.isalnum():
        print(s,"is NOT alphanumeric")
    else:
        print(s, "is alphanumeric")

Output:

cyberpunk is NOT alphanumeric
x10 is alphanumeric
hacker is NOT alphanumeric
x15 is alphanumeric
animegirl is NOT alphanumeric
x20 is alphanumeric

But the above algorithm will fail on following list of words:

words = ["with space", "speci@lChar", "140"]

and the Output is:

with space is alphanumeric
speci@lChar is alphanumeric
140 is alphanumeric

Conclusion

As explained in the python 3.6.6 documentation, we need to check each character of a word and if any of the given condition fails, a word will not be considered as alphanumeric


Edited

Following algorithm can help us by checking each character

words = ["cyberpunk" ,"x10", "hacker" , "x15" , "animegirl" , "x20", "with space", "speci@lChar", "140"]
for word in words:
    isAlpha = False
    isNum = False
    for c in word:
        if c.isalpha():
            isAlpha = True
        elif c.isdigit():
            isNum = True
        else:
            isAlpha = isNum = False
            break
    if isAlpha and isNum:
        print(word, "is alphanumeric")
    else:
        print(word, "is NOT alphanumeric")

Output:

cyberpunk is NOT alphanumeric
x10 is alphanumeric
hacker is NOT alphanumeric
x15 is alphanumeric
animegirl is NOT alphanumeric
x20 is alphanumeric
with space is NOT alphanumeric
speci@lChar is NOT alphanumeric
140 is NOT alphanumeric

Solution 4:[4]

Look at the documentation for isalnul.

Return true if all characters in the string are alphanumeric and there >is at least one character, false otherwise.

For 8-bit strings, this method is locale-dependent.

Then as all the characters of the list words are alphanumeric (single letters or numbers) isalnum returns True for all.

In this sucks we have the character "" (blank space) that is not alphanumeric. Then isalnum returns us False

' '.isalnum() #Return False

If you want to find out whether or not they have numbers you can do something like this:

from string import digits

def have_numbers(s):
    for digit in digits:
        if digit in s:
            return True
    return False

have_numbers("cyberpunk") # return False
have_numbers("x10") # return True

Solution 5:[5]

there are a nice code for similar case

if __name__ == '__main__':
s = input()
for method in [str.isalnum, str.isalpha, str.isdigit, str.islower, str.isupper]:
    print(any(method(c) for c in s))

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Becca codes
Solution 3
Solution 4
Solution 5 Mohamed Al-sarf