【问题标题】:Looping through a nested list filter循环通过嵌套列表过滤器
【发布时间】:2021-01-17 18:33:37
【问题描述】:

对不起,如果标题不正确,我是新手,正在自学 Python。我有一个包含这个的当前程序...

    # Prompt function List
    whatIsYourNameL = ['my name is','i am called', 'you may call me']
    # Do this is if prompted
    def whatIsYourName()
        print(f'Hello {youName}')

    while True:

        if list(filter(lambda x: x in choice.lower(), changeYourNameList)):
            changeYourName()
        elif list(filter(lambda x: x in choice.lower(), whatIsYourNameList)):
            whatIsYourName()
        elif list(filter(lambda x: x in choice.lower(), whatIsMyNameList)):
            whatIsMyName()

到目前为止,我在嵌套的 if - elif 语句中使用了相同的过滤器并更改了函数名称。我现在正试图通过尝试做这样的事情来简化......

     # Prompt function List
     whatIsYourNameL = ['my name is','i am called', 'you may call me']
     # Do this is if prompted
     def whatIsYourName()
        print(f'Hello {youName}')

     FunctList = ['changeYourName','whatIsYourName','whatIsMyName']
     c = choice.lower
     while True:    
    
        for funct in range(len(FunctList)):
            if list(filter(lambda x: x in c, f'{FunctList[funct]}L')):
                f'{FunctList[funct]}()'

关于我如何做到这一点的任何想法?

【问题讨论】:

  • 您的代码中的c 是什么?
  • 你能在FuncList定义中存储实际函数(即去掉引号)吗?这将使问题变得微不足道

标签: python list filter nested


【解决方案1】:

我不清楚您的过滤器应该如何工作,因为我不确定您的代码中的 c 是什么,但这演示了构建函数列表然后循环遍历该列表的概念:

def changeYourName():
    print("change your name")

def whatIsYourName():
    print("what is your name?")

def whatIsMyName():
    print("what is my name?")

FunctList = [changeYourName, whatIsYourName, whatIsMyName]

for f in FunctList:
    f()

请注意,函数本身进入列表,而不是与其名称对应的字符串。当您使用 for f in FunctList 遍历该列表的内容时,每个元素 (f) 都是您可以调用的函数,即 f()

(编辑)

查看您更新的问题,您似乎正在尝试将前缀列表与每个函数相关联,然后调用与前缀匹配的函数?我可能会这样做——因为您不仅要检查匹配项,而且还想去掉前缀(您的代码没有为 youName 定义值,但根据上下文,您似乎想要提取它来自“我的名字是”字符串),对我来说将所有这些逻辑放在一个函数中是有意义的,这样您就不必在两个不同的地方处理前缀:

from typing import Callable, Iterable


def strip_prefix_and_call(
    prefixes: Iterable[str],
    func: Callable[[str], None],
    arg: str
) -> None:
    """Given an arg that starts with one of a set of prefixes,
    strip the prefix from the arg and invoke the given func.
    Raises ValueError if none of the prefixes is in the arg."""
    try:
        prefix = [p for p in prefixes if arg.lower().startswith(p)][0]
        func(arg[len(prefix):])
    except IndexError:
        raise ValueError(f"{arg} does not start with any prefix in {prefixes}")


def my_name_is(name: str):
    print(f"Hello {name}")


def do_this_thing(command: str):
    print(f"I don't know how to {command}")


while True:
    choice = input("? ")

    for prefixes, func in [
        (['my name is ', 'i am called ', 'you may call me '], my_name_is),
        (['please ', 'i order you to ', 'would you kindly '], do_this_thing),
    ]:
        try:
            strip_prefix_and_call(prefixes, func, choice)
            break
        except ValueError:
            continue
? My name is Bob
Hello Bob
? Would you kindly assemble a martini
I don't know how to assemble a martini

【讨论】:

  • "c" 是用户编写的字符串,例如“我的名字是大卫”或“他们叫我大卫”。原始函数查找了一个名为“whatIsYourNameL”的列表,并在该列表中找到了一个匹配的“c”子字符串,然后运行了函数“whatIsYourName()”
  • 其他功能在哪里?如果我们能够完整地查看代码并对总体目标进行一些解释,将会有所帮助;当既没有代码也没有文档时,不可能对目的进行三角测量。 :)
  • 在我的原始代码中,过滤器是位于嵌套 if else 语句中的众多过滤器之一。因此,如果过滤器在其列表中没有找到 c 的子字符串,它将转到下一个 elif 并查看 c 的子字符串是否在其列表中并调用该函数
  • 对不起,与我的要求无关。我有一个功能可以在其他地方去除前缀。我只有一遍又一遍地重复的代码,唯一改变的是列表的名称和 def 的名称。我确信可以将这段代码放入循环中并以某种方式从列表中更改名称,但我所有的努力都失败了。
  • 我认为您尝试做的事情的原则应该在我给您的代码的某些部分中说明,但是如果您需要能够完全复制您正在做的工作的代码您现有的代码,如果没有看到您现有的代码,就不可能提供它。祝你好运!
猜你喜欢
  • 2021-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-18
  • 2017-05-09
  • 2020-07-07
相关资源
最近更新 更多