I m trying to solve a hackerrank challenge:
Sample Input
S = "qA2"In the first line, print
Trueif S has any alphanumeric characters. Otherwise, printFalse.
In the second line, printTrueif S has any alphabetical characters. Otherwise, printFalse.
In the third line, printTrueif S has any digits. Otherwise, printFalse.
In the fourth line, printTrueif S has any lowercase characters. Otherwise, printFalse.
In the fifth line, printTrueif S has any uppercase characters. Otherwise, printFalse.
I know there are simpler way to do it but I d like to use eval().
Rather than having multiple line with all the methods, I wanted to use a list with the methods in it (cmd here) then go through it with a for loop, and the eval() should transform it to a method (eval(i+"."+j)). If any of the character i in list(s) returns True, it print true.
Code/Attempt:
if __name__ == '__main__':
s = input()
cmd=["isalnum()","isalpha()"]
for j in cmd:
print (any([eval(i+"."+j) for i in list(s)]))
Traceback/Error:
Traceback (most recent call last):
File "Solution.py", line 5, in <module>
print (any([eval(i+"."+j) for i in list(s)]))
File "Solution.py", line 5, in <listcomp>
print (any([eval(i+"."+j) for i in list(s)]))
File "<string>", line 1, in <module>
NameError: name 'q' is not defined
-
2Why would you do that? Why use strings and not the functions themselves?juanpa.arrivillaga– juanpa.arrivillaga2019年06月13日 18:26:40 +00:00Commented Jun 13, 2019 at 18:26
-
cauz I want to make the function iterable rather than copy past, I have only 5 methods to apply here. what if I have 100?adriencdw– adriencdw2019年06月13日 20:55:07 +00:00Commented Jun 13, 2019 at 20:55
-
You still don't have to do it this way. That's why I said, use the functions themselvesjuanpa.arrivillaga– juanpa.arrivillaga2019年06月13日 22:35:38 +00:00Commented Jun 13, 2019 at 22:35
1 Answer 1
This is having an issue because when your strings are concatenated in the eval() statement you get something resembling q.isalnum() when you really want 'q'.isalnum(). The first one is using q like a variable when you really want to call the method on the character 'q'. Something like this:
if __name__ == '__main__':
s = input()
cmd=["isalnum()","isalpha()"]
for j in cmd:
print (any([eval("'{}'.{}".format(i, j)) for i in list(s)]))
Instead of using strings as commands, you could just use the function itself:
cmd=[str.isalnum, str.isalpha]
and then you wouldn't need to use eval as it would just be:
if __name__ == '__main__':
s = input()
cmd=[str.isalnum,str.isalpha]
for j in cmd:
print (any([j(i) for i in list(s)]))
Edit:
For the sake of completeness, you could also remove the brackets inside the any() to create a generator rather than a list comprehension. This is good because the generator will stop once it first reaches the first True result whereas a list comprehension will evaluate for the whole string. You also don't need to convert s into a list as strings are iterable on their own. You're then left with:
any(j(i) for i in s)
6 Comments
'example'.isalpha() actually just gets translated to str.isalpha('example'). The first one is just syntactic sugar for the second and in this case str is the class of 'example'. In my example, it was easier to use the str.isalpha because I could then pass the string as a parameter rather than having to build up a function call.