在Python中动态循环函数列表

bbmckpt7  于 2023-05-16  发布在  Python
关注(0)|答案(9)|浏览(186)

我想看看是否可以在函数中运行函数列表。我能找到的最接近的方法是遍历整个模块。我只想使用预先选择的函数列表。
这是我最初的问题:
1.给定一个字符串,检查每个字母以查看是否满足5个测试中的任何一个。
1.如果至少有1个字母通过检查,则返回True。
1.如果字符串中的所有字母都未通过检查,则返回False。
1.对于字符串中的每个字母,我们将检查这些函数:isalnum(),isalpha(),isdigit(),islower(),isupper()
1.每个测试的结果应打印到不同的行。
样品输入

qA2

示例输出(必须打印到单独的行,如果至少有一个字母通过,则为True,或者所有字母均未通过每个测试,则为false):

True
    True
    True
    True
    True

我写这个是为了测试。当然,我可以只写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方法(我想这叫内省方法?)

raw = 'ABC'

    meths = ['isalnum', 'isalpha', 'isdigit', 'islower', 'isupper']
    for m in meths: 
        print any(getattr(c,m)() for c in raw)

列表理解方式:

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]
uoifb46i

uoifb46i1#

你在函数列表中循环的方式有点不对。这将是一个有效的方法来做到这一点。需要存储在列表中的函数是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)。
上面是一个更pythonic的方法来做到这一点,但只是作为一个学习工具,我写了一个工作版本,它尽可能地匹配你如何尝试去做,以显示你在哪里出错。以下是评论:

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
7kqas0il

7kqas0il2#

好了,第一个问题很简单。最简单的方法就是去做

def foo(raw):
  for c in raw:
    if c.isalpha(): return True
    if c.isdigit(): return True
    # the other cases
  return False

永远不要忽视最简单的事情,可以工作。
现在,如果你想做 * 动态 * -这是你可能需要的魔术关键字,你想应用这样的东西(从another question抄袭):

meths = [isalnum, isalpha, isdigit, islower, isupper]
for c in raw:    
  for m in meths:
    getattr(c, m)()

警告,这是未经测试的代码,旨在给予你的想法。这里的关键概念是对象的方法和其他任何东西一样都是属性,例如getattr("a", "isalpha")()执行以下操作:

  • 使用getattr"a"的属性字典中搜索名为isalpha的方法
  • 返回该方法本身--<function isalpha>
  • 然后使用()调用该方法,()是Python中的函数应用操作符。

请看这个例子:

In [11]: getattr('a', 'isalpha')()
Out[11]: True
hc2pp10m

hc2pp10m3#

所有其他答案都是正确的,但由于您是初学者,我想指出您代码中的问题:

lst = [raw[i].isalnum(),raw[i].isalpha(),raw[i].isdigit(),raw[i].islower(),raw[i].isupper()]

第一:不确定 i 当前在代码中的哪个值,但它似乎指向字符串中的某个地方-这导致单个字符被评估,而不是整个字符串 raw
第二:当你构建列表的时候,你已经在调用你想要插入的方法了,这会导致插入的不是函数本身,而是它们的返回值(这就是为什么你会在print语句中看到所有的 True 值)。
尝试按如下方式更改代码:

lst = [raw.isalnum, raw.isalpha, raw.isdigit, raw.islower, raw.isupper]
utugiqy6

utugiqy64#

我猜你是在验证密码的复杂性,我还要说,软件接受输入并说“False”,并且没有任何迹象表明 * 为什么 * 是用户敌对的,所以最重要的不是“如何循环嵌套的char函数代码wizardry(*)”,而是“给予良好的反馈”,并建议更像这样的东西:

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)

在线试用at repl.it
正则表达式搜索在一次调用中检查字符和数字的范围,这比字符上的循环更简洁。
(PS.你们的职能重叠;具有匹配'isupper'、'islower'和'isnumeric'的字符的字符串已经覆盖了'isadigit'和'isalnum'。更有趣的是处理像!这样的字符,它们不是upper,lower,digits或alnum。
(*)函数魔法像其他答案一样通常正是我会回答的,但是已经有太多的答案了,我不妨用另一种方式来回答:P

6fe3ivhb

6fe3ivhb5#

回答最初的问题:

raw = 'asdfa3fa'
functions = [str.isalnum, str.isalpha, str.isdigit, str.islower, str.isupper]
isanything = [func(raw) for func in functions]
print repr(isanything)
fd3cxomn

fd3cxomn6#

因为你正在遍历一个简单项的列表,并试图找到all的函数是否有any有效的结果,所以你可以简单地定义你想在输入上调用的函数列表并返回它。下面是一个相当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
>>>
sg2wtvxw

sg2wtvxw7#

您可以使用introspection循环遍历对象的所有属性,无论它们是函数还是其他类型。
但是你可能不想在这里这样做,因为str有很多函数属性,而你只对其中的五个感兴趣。最好还是像你做的那样,把你想要的五个列出来。
同样,如果你不想的话,你也不需要循环遍历字符串的每个字符;这些函数已经查看了整个字符串。

qni6mghb

qni6mghb8#

查看针对您的问题的这一行解决方案。这个问题来自HackerRank。我使用内置的getattr函数循环一系列函数。

s='qA2'
[print(bool(list(filter(lambda x : getattr(x, func)(),s)))) for func in ['isalnum','isalpha','isdigit','islower','isupper']]
d5vmydt9

d5vmydt99#

我使用map()函数实现了它:

s = 'qA2'
functions = [str.isalnum, str.isalpha, str.isdigit, str.islower, str.isupper]
for i in functions:
    true_list = map(i, list(s))
    if True in true_list:
        print(True)
    else:
        print(False)

相关问题