14

Trying to get python to return that a string contains ONLY alphabetic letters AND spaces

string = input("Enter a string: ")

if all(x.isalpha() and x.isspace() for x in string):
    print("Only alphabetical letters and spaces: yes")
else:
    print("Only alphabetical letters and spaces: no")

I've been trying please and it comes up as Only alphabetical letters and spaces: no I've used or instead of and, but that only satisfies one condition. I need both conditions satisfied. That is the sentence must contain only letters and only spaces but must have at least one of each kind. It must not contain any numerals.

What am I missing here for python to return both letters and spaces are only contained in the string?

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
sithlorddahlia
  • 157
  • 1
  • 1
  • 11

9 Answers9

24

A character cannot be both an alpha and a space. It can be an alpha or a space.

To require that the string contains only alphas and spaces:

string = input("Enter a string: ")

if all(x.isalpha() or x.isspace() for x in string):
    print("Only alphabetical letters and spaces: yes")
else:
    print("Only alphabetical letters and spaces: no")

To require that the string contains at least one alpha and at least one space:

if any(x.isalpha() for x in string) and any(x.isspace() for x in string):

To require that the string contains at least one alpha, at least one space, and only alphas and spaces:

if (any(x.isalpha() for x in string)
    and any(x.isspace() for x in string)
    and all(x.isalpha() or x.isspace() for x in string)):

Test:

>>> string = "PLEASE"
>>> if (any(x.isalpha() for x in string)
...     and any(x.isspace() for x in string)
...     and all(x.isalpha() or x.isspace() for x in string)):
...     print "match"
... else:
...     print "no match"
... 
no match
>>> string = "PLEASE "
>>> if (any(x.isalpha() for x in string)
...     and any(x.isspace() for x in string)
...     and all(x.isalpha() or x.isspace() for x in string)):
...     print "match"
... else:
...     print "no match"
... 
match
rob mayoff
  • 375,296
  • 67
  • 796
  • 848
  • Okay, then this method doesn't fit what I need. I need for BOTH to return True so that way it states `Only alphabetical letters and spaces: yes` with `please ` I just tried this: `alphabet = string.isalpha() spaces = string.isspace() if alphabet == True and spaces == True` but still no go. Any other suggestions? – sithlorddahlia Apr 05 '15 at 18:08
  • I don't understand your comment. Please edit your original question to include your new requirements. – rob mayoff Apr 05 '15 at 18:12
  • It's not a new requirement, it's the same requirement. Python needs to read that both only letters and spaces are in the string. Take `please `for example. It has both spaces and letters. `please` has only letters but no spaces. So both criteria aren't met. – sithlorddahlia Apr 05 '15 at 18:16
  • 1
    Do you mean it needs to contain at least one letter and at least one space? Is it allowed to also contain non-letter non-space characters? – rob mayoff Apr 05 '15 at 18:17
  • It can only contain letters and spaces. `please my email` has only letters and spaces so python should print `Only alphabetical letters and spaces: yes`. `read my 5 emails` does have letters and spaces, but it has a number, so `Only alphabetical letters and spaces: no` – sithlorddahlia Apr 05 '15 at 18:20
  • This is close, very close! Only I have an issue with a word and no space. `PLEASE` returns `Only alphabetical letters and spaces: yes`, but it doesn't have any spaces. It's just the word. – sithlorddahlia Apr 05 '15 at 18:34
  • It works for me. See my updated answer. If it's not working for you, copy and paste your new code into your original question. – rob mayoff Apr 05 '15 at 18:38
  • I got it! Thank you very much for all your help and useful information! Have a great day, sir! – sithlorddahlia Apr 05 '15 at 18:43
3

The correct solution would use an or.

string = input("Enter a string: ")

if all(x.isalpha() or x.isspace() for x in string):
    print("Only alphabetical letters and spaces: yes")
else:
    print("Only alphabetical letters and spaces: no")

Although you have a string, you are iterating over the letters of that string, so you have one letter at a time. So, a char alone cannot be an alphabetical character AND a space at the time, but it will just need to be one of the two to satisfy your constraint.

EDIT: I saw your comment in the other answer. alphabet = string.isalpha() return True, if and only if all characters in a string are alphabetical letters. This is not what you want, because you stated that you want your code to print yes when execute with the string please, which has a space. You need to check each letter on its own, not the whole string.

Just to convince you that the code is indeed correct (well, ok, you need to execute it yourself to be convinced, but anyway):

>>> string = "please "
>>> if all(x.isalpha() or x.isspace() for x in string):
    print("Only alphabetical letters and spaces: yes")
else:
    print("Only alphabetical letters and spaces: no")


Only alphabetical letters and spaces: yes

EDIT 2: Judging from your new comments, you need something like this:

def hasSpaceAndAlpha(string):
    return any(char.isalpha() for char in string) and any(char.isspace() for char in string) and all(char.isalpha() or char.isspace() for char in string)

>>> hasSpaceAndAlpha("text# ")
False
>>> hasSpaceAndAlpha("text")
False
>>> hasSpaceAndAlpha("text ")
True

or

def hasSpaceAndAlpha(string):
    if any(char.isalpha() for char in string) and any(char.isspace() for char in string) and all(char.isalpha() or char.isspace() for char in string):
        print("Only alphabetical letters and spaces: yes")
    else:
        print("Only alphabetical letters and spaces: no")

>>> hasSpaceAndAlpha("text# ")
Only alphabetical letters and spaces: no
>>> hasSpaceAndAlpha("text")
Only alphabetical letters and spaces: no
>>> hasSpaceAndAlpha("text ")
Only alphabetical letters and spaces: yes
codingEnthusiast
  • 3,800
  • 2
  • 25
  • 37
3

Actually, it is an pattern matching exercise, so why not use pattern matching?

import re
r = re.compile("^[a-zA-Z ]*$")
def test(s):
    return not r.match(s) is None  

Or is there any requirement to use any() in the solution?

flaschbier
  • 3,910
  • 2
  • 24
  • 36
  • Is there a reason you use `return not r.match(s) is None` rather than `return bool(r.match(s))`? – Chris Nov 06 '15 at 20:40
  • 1
    Maybe. I prefer coding variants that can be understood with the least possible thinking when coming back to the code after a year or so. Openly dealing with the return value of `r.match()` might support this. What I really should have done differently is the name of the function ;) – flaschbier Nov 08 '15 at 14:51
2

You need any if you want at least one of each in the string:

if any(x.isalpha() for x in string) and any(x.isspace() for x in string):

If you want at least one of each but no other characters you can combine all,any and str.translate , the following will only return True if we have at least one space, one alpha and contain only those characters.

 from string import ascii_letters

 s = input("Enter a string: ")

 tbl = {ord(x):"" for x in ascii_letters + " "}

if all((any(x.isalpha() for x in s),
   any(x.isspace() for x in s),
   not s.translate(tbl))):
    print("all good")

Check if there is at least one of each with any then translate the string, if the string is empty there are only alpha characters and spaces. This will work for upper and lowercase.

You can condense the code to a single if/and:

from string import ascii_letters

s = input("Enter a string: ")
s_t = s.translate({ord(x):"" for x in ascii_letters})

if len(s_t) < len(s) and s_t.isspace():
    print("all good")

If the length of the translated string is < original and all that is left are spaces we have met the requirement.

Or reverse the logic and translate the spaces and check if we have only alpha left:

s_t = s.translate({ord(" "):"" })
if len(s_t) < len(s) and s_t.isalpha():
    print("all good")

Presuming the string will always have more alphas than spaces, the last solution should be by far the most efficient.

Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
2
    string = input("Enter a string: ")
    st1=string.replace(" ","").isalpha()
    if (st1):
        print("Only alphabetical letters and spaces: yes")
    else:
        print("Only alphabetical letters and spaces: no")
1

You can use regex for doing that action

import re


name = input('What is your name ?')

if not re.match("^[a-z A-Z]*$", name):
    print("Only Alphabet and Space are allowed")
else:
    print("Hello" ,name)
0
// remove spaces and question is only alphanumeric
def isAlNumAndSpaces(string):
    return string.replace(" ","").isalnum()
strTest = input("Test a string: ")
if isAlNumAndSpaces(strTest):
    print("Only alphabetical letters and spaces: yes")
else:
    print("Only alphabetical letters and spaces: no")
  • OP .. check the additions of Arpad and lear from it how to post a complete and valid answer. End of Review. – ZF007 Oct 15 '20 at 09:39
0

use a pattern match like this

import re
alpha_regex = "^[a-z A-Z]+$"
if re.match(alpha_regex, string):
   print("Only alphabetical letters and spaces: yes")
else:
   print("Only alphabetical letters and spaces: no")
Misterlen
  • 61
  • 2
0

the usage of isalpha() is less specific than using regex.

isalpha will return true not only for [a-zA-Z] but for other alphabetic unicodes.

use bool(re.match('^[a-zA-Z\s]+$', name)

IlayG01
  • 80
  • 1
  • 7