动态遍历Python函数中的函数列表
我想看看是否可以在函数中运行函数列表。我能找到的最接近的东西就是在整个模块中循环。我只想使用预先选定的函数列表 这是我最初的问题:动态遍历Python函数中的函数列表,python,list,loops,Python,List,Loops,我想看看是否可以在函数中运行函数列表。我能找到的最接近的东西就是在整个模块中循环。我只想使用预先选定的函数列表 这是我最初的问题: 给定一个字符串,检查每个字母,看看5个测试中是否有一个符合要求 如果至少有1个字母通过检查,则返回True 如果字符串中的所有字母都未通过检查,则返回False 对于字符串中的每个字母,我们将检查以下函数:isalnum()、isalpha()、isdigit()、islower()、isupper() 每次测试的结果应打印到不同的行 样本输入 qA2 样
qA2
样本输出(必须打印到单独的行,如果至少有一个字母通过,则为True;如果每个测试都失败,则为false):
我写这个是为了一个测试。当然,我可以只写5组不同的代码,但这看起来很难看。然后我开始想我是否可以循环通过他们要求的所有测试
仅用于一个测试的代码:
raw = 'asdfaa3fa'
counter = 0
for i in xrange(len(raw)):
if raw[i].isdigit() == True: ## This line is where I'd loop in diff func's
counter = 1
print True
break
if counter == 0:
print False
我尝试运行包含所有测试的循环失败:
raw = 'asdfaa3fa'
lst = [raw[i].isalnum(),raw[i].isalpha(),raw[i].isdigit(),raw[i].islower(),raw[i].isupper()]
counter = 0
for f in range(0,5):
for i in xrange(len(raw)):
if lst[f] == True: ## loop through f, which then loops through i
print lst[f]
counter = 1
print True
break
if counter == 0:
print False
那么,我该如何修复此代码以满足上面的所有规则呢
使用来自所有注释的信息-此代码满足上述规则,并动态循环通过每个方法。
raw = 'ABC'
functions = [str.isalnum, str.isalpha, str.isdigit, str.islower, str.isupper]
for func in functions:
print any(func(letter) for letter in raw)
getattr方法(我认为这称为内省方法?
列表理解方法:
from __future__ import print_function ## Changing to Python 3 to use print in list comp
raw = 'ABC'
functions = [str.isalnum, str.isalpha, str.isdigit, str.islower, str.isupper]
solution = [print(func(raw)) for func in functions]
由于您正在循环浏览一个简单项列表,并尝试查找其中一个函数是否具有有效的结果,因此您可以简单地定义要调用输入并返回的函数列表。下面是一个相当类似于python的例子,说明您正在努力实现的目标:
def checker(checks, value):
return all(any(check(r) for r in value) for check in checks)
测试一下:
>>> def checker(checks, value):
... return all(any(check(r) for r in value) for check in checks)
...
>>> checks = [str.isalnum, str.isalpha, str.isdigit, str.islower, str.isupper]
>>> checker(checks, 'abcdef123ABC')
True
>>> checker(checks, 'abcdef123')
False
>>>
可以使用循环遍历对象的所有属性,无论它们是函数还是其他类型
但是,您可能不想在这里这样做,因为str
有很多函数属性,您只对其中五个感兴趣。也许最好像你那样做,把你想要的五个列出来
此外,如果不想循环,也不需要循环字符串的每个字符;这些函数已经查看了整个字符串。要回答原始问题:
raw = 'asdfa3fa'
functions = [str.isalnum, str.isalpha, str.isdigit, str.islower, str.isupper]
isanything = [func(raw) for func in functions]
print repr(isanything)
在函数列表中循环的方式有点不正确。这将是一种有效的方法。需要存储在列表中的函数是str.funcname给定的通用字符串函数。一旦有了这些函数列表,就可以使用for循环遍历它们,并将其视为普通函数
raw = 'asdfaa3fa'
functions = [str.isalnum, str.isalpha, str.isdigit, str.islower, str.isupper] # list of functions
for fn in functions: # iterate over list of functions, where the current function in the list is referred to as fn
for ch in raw: # for each character in the string raw
if fn(ch):
print(True)
break
样本输出:
Input Output
===================================
"qA2" -----> True True True True True
"asdfaa3fa" -----> True True True True
我还注意到您似乎在迭代中使用索引,这让我觉得您可能来自C/C++之类的语言。for-in-loop构造在python中非常强大,因此我将仔细阅读它(y)
以上是一种更具python风格的方法,但作为一种学习工具,我编写了一个工作版本,它尽可能匹配您尝试这样做的方式,以向您展示您的具体错误。以下是评论:
raw = 'asdfaa3fa'
lst = [str.isalnum, str.isalpha, str.isdigit, str.islower, str.isupper] # notice youre treating the functions just like variables and aren't actually calling them. That is, you're writing str.isalpha instead of str.isalpha()
for f in range(0,5):
counter = 0
for i in xrange(len(raw)):
if lst[f](raw[i]) == True: # In your attempt, you were checking if lst[f]==True; lst[f] is a function so you are checking if a function == True. Instead, you need to pass an argument to lst[f](), in this case the ith character of raw, and check whether what that function evaluates to is true
print lst[f]
counter = 1
print True
break
if counter == 0:
print False
好的,第一个问题很简单。做这件事的简单方法就是去做
def foo(raw):
for c in raw:
if c.isalpha(): return True
if c.isdigit(): return True
# the other cases
return False
永远不要忽视最简单的事情
现在,如果你想动态地做这件事——这是你可能需要的神奇关键词,你需要应用如下内容(抄袭自):
警告,这是未经测试的代码,旨在提供您的想法。这里的关键概念是,对象的方法与其他方法一样都是属性,因此,例如getattr(“a”,“isalpha”)()
执行以下操作:
- 使用
在getattr
的属性字典中搜索名为“a”
isalpha
- 返回该方法本身--
- 然后使用Python中的函数应用程序操作符
调用该方法()
In [11]: getattr('a', 'isalpha')()
Out[11]: True
所有其他答案都是正确的,但由于您是初学者,我想指出代码中的问题:
lst = [raw[i].isalnum(),raw[i].isalpha(),raw[i].isdigit(),raw[i].islower(),raw[i].isupper()]
第一:不确定我当前在代码中截取了哪个值,但它似乎指向了字符串中的某个地方——这会导致计算单个字符,而不是整个字符串
第二:当您构建列表时,您已经在调用要插入的方法,这会导致插入的不是函数本身,而是它们的返回值(这就是为什么您在print语句中看到所有这些真值)
尝试按以下方式更改代码:
lst = [raw.isalnum, raw.isalpha, raw.isdigit, raw.islower, raw.isupper]
我猜你是在验证密码的复杂性,我还想说的是,软件接受输入并显示“False”,并且没有任何迹象表明用户为什么对它怀有敌意,所以最重要的不是“如何循环嵌套的char函数代码向导(*)”,而是“提供良好的反馈”,并建议类似于:
raw = 'asdfaa3fa'
import re
def validate_password(password):
""" This function takes a password string, and validates it
against the complexity requirements from {wherever}
and returns True if it's complex enough, otherwise False """
if not re.search('\d', password):
print("Error: password needs to include at least one number")
return False
elif not re.search('[a-z]', password):
print("Error: password must include at least one lowercase letter")
return False
elif not re.search('[A-Z]', password):
print("Error: password must include at least one uppercase letter")
return False
print("Password is OK")
return True
validate_password(raw)
在线尝试
正则表达式搜索检查一次调用中字符和数字的范围,这比循环字符更简洁
(请注意,函数重叠;包含与“isupper”、“islower”和“isnumeric”匹配的字符的字符串已经包含了“isadigit”和“isalnum”。更有趣的是处理像!
这样的字符,它们不是上、下、数字或alnum)
(*)函数向导和其他答案一样,通常我会回答,但是已经有太多的答案,所以我可以用另一种方法来回答:p检查一下你的问题的这一行解决方案。这个问题来自HackerRank。我使用内置的getattr函数遍历函数列表
s='qA2'
[print(bool(list(filter(lambda x : getattr(x, func)(),s)))) for func in ['isalnum','isalpha','isdigit','islower','isupper']]
为什么不把所有这些测试都打包成一个名为
isValid()
?嗯……让我现在就重新编写代码,看看这会给我带来什么。将使用新版本进行编辑。一个角色如何通过这两个岛
lst = [raw.isalnum, raw.isalpha, raw.isdigit, raw.islower, raw.isupper]
raw = 'asdfaa3fa'
import re
def validate_password(password):
""" This function takes a password string, and validates it
against the complexity requirements from {wherever}
and returns True if it's complex enough, otherwise False """
if not re.search('\d', password):
print("Error: password needs to include at least one number")
return False
elif not re.search('[a-z]', password):
print("Error: password must include at least one lowercase letter")
return False
elif not re.search('[A-Z]', password):
print("Error: password must include at least one uppercase letter")
return False
print("Password is OK")
return True
validate_password(raw)
s='qA2'
[print(bool(list(filter(lambda x : getattr(x, func)(),s)))) for func in ['isalnum','isalpha','isdigit','islower','isupper']]