当前位置: 首页 > 知识库问答 >
问题:

理解旧式Python现在给出错误的一行代码

韩智明
2023-03-14
cats = CatService.find_all()
data['value'] = [cat for cat in cats if cat.label == data['value']][0].name

我无法理解这行用Python写的是什么。它曾经工作,但现在我得到一个列表索引超出范围错误。

cats[0]。name给出了结果,并且在运行上述语句之前不是null,但我仍然得到了错误。

遗留代码如上所述以一行程序编写。当我得到这个错误时,我不得不像下面那样剖析它。

我试图用这种格式编写代码以进行分析和调试。但是我没有得到错误。我想这不是一行的正确翻译:

for cat in cats:
    if cat.label == data['value']:
        print("cat match is " + cat.label)
        data['value'] = cats[0].name
    else:
        print("cat non-match is " + cat.label)

编辑:目前我的假设是翻译的代码是正确的,没有错误。但是一行确实给出了错误。不知道为什么。列表中存在700个值。埃里克在下面提供的另一个类似的翻译也有效。(Erik后来改了,所以加在这里)

if data['value'] in [topic.label for topic in topics]: data['value'] = topics[0].name

共有3个答案

常哲彦
2023-03-14

就我个人而言,我觉得这两个现有的答案已经很好了,但我要看看我是否可以更明确地将其分解。首先,我建议阅读这篇文章,它对列表理解给出了很好的解释,以及如何在for循环中看到它们的等价物。

所以,这是最初的一句话:

data['value'] = [cat for cat in cats if cat.label == data['value']][0].name

您的for循环版本没有做完全相同的事情。最值得注意的是,您正在抓取原始列表中的第一项,而不是由列表理解构建的列表。让我们一步一步地扩展原来的一行。首先,我们将把列表理解分配给一个变量,以便更清晰:

matching_cats = [cat for cat in cats if cat.label == data['value']]
data['value'] = matching_cats[0].name

如您所见,data['value']最终指向匹配猫列表中第一只猫的名字。这就是您得到错误的地方:无论出于何种原因,没有猫匹配您的条件,因此匹配猫是一个空列表,[],因此没有第一个元素匹配猫[0]

现在,如果我们将列表理解扩展到for循环:

matching_cats = []
for cat in cats:
    if cat.label == data['value']:
        matching_cats.append(cat)
data['value'] = matching_cats[0].name

这是对原始代码的完全直译,当使用相同的数据时,应该会得到相同的错误。同样,它构建了一个匹配条件的所有CAT的列表,然后将data['value']设置为找到的第一个匹配项的名称。

正如chepner和Chen A的回答中指出的,这个代码有两个问题:

  1. 正如你所发现的,如果没有猫符合条件,它就会崩溃
  2. 即使它找到了一只匹配的猫,它也会继续检查所有其他的猫,即使最终你只想要一只。那是浪费

正因为如此,我建议使用这些答案中给出的替代代码,一旦找到匹配就尽早结束迭代(并在没有匹配的情况下做好准备)。

拓拔麒
2023-03-14

我一开始不会使用列表理解,因为你不想要匹配猫的列表;你只想要第一只匹配的猫。我会写信的

cats = CatService.find_all()
for cat in cats:
    if cat.label == data['value']:
        data['value'] = cat.name
        break

类似的循环替代方案可能是

if any((found:=cat).label == data['value'] for cat in cats):
    data['value'] = found.name

any短路,因此如果找到匹配的cat,found将绑定到匹配的对象。如果未找到匹配项,any返回False,并且找到的绑定到的对象(即列表中的最后一个cat)不相关或未使用。

我让每个读者自己决定哪一个更具可读性。它们的性能应该相当。

罗寒
2023-03-14

您遇到的错误非常不言自明;这意味着您正在访问的列表中没有项目。

您正在使用列表理解的结果更新数据['value'][cat for cat in cat if cat.label==data['value']][0]。名称。请注意,您在返回的列表中中继[0]元素。当列表为空时,您将遇到此错误。

您不能真正从list理解中提取值,因为它可能有0个元素。你必须在一个for循环中运行它,

for cat in cats:
  if cat.label == data['value']:
    data['value'] = cat.name
    break

请注意,您可能希望在比赛后Rest。

如果您分解更新的代码,

data['value'] = [cat for cat in cats if cat.label == data['value']][0].name

这将比较cats中的每个cat,并创建一个所有匹配cat的列表(由于比较cat.label==data['value'],因此列表中可能会有0、1或N个cat。

然后取第一个项目的名称:[

上面的代码片段实现了代码的意图;找到第一只匹配的猫并返回它的名字。

 类似资料:
  • #这是我试图在我的电脑上运行的python代码,但它是Thowrsero,但我没有找到错误的图像回溯(最近的一次调用):文件“c:/Users/user/Desktop/projetcs/machine learning/mc1.py”,第4行,df=df['Adj.Open'、'Adj.High'、'Adj.Low'、'Adj.Close'、'Adj.Volume']]文件“c:\Users\u

  • 我在Laravel与Carbon合作。 问题:我需要使用carbon::now()制作一个碳日期- 下面是我的功能 以下是输出: 类似的结果是给三月(当我给$月=3) 我不明白这里的问题。 提前谢谢。

  • 在https://github.com/thomashbailey/vapor-auth观看了本教程之后,我正在练习vapor服务器。从代码中可以看到,createUser的表现很好,但是如果你尝试登录,弹出401错误,我问你一个问题。 不是登录时给代币的代码吗?我不知道.如果你能告诉我,我将不胜感激。

  • 我有一个使用gradle构建系统的项目,我愿意在其中添加新的遗迹监控。 该项目(包括New Relic)在Linux(Fedora 20)上运行良好,但不会构建在我的Mac开发系统上,并给出一个错误,说明已加载代理JAR,但代理未能初始化。 以下是错误的完整日志: 我还测试了一个新生成的基本项目,但它以完全相同的错误失败。 如果有必要的话,我使用JDK 1.7u55版本。 谢谢

  • 我正在尝试将JOOQ与最新版本4.0.0的vertx一起使用。我想通过gradle生成我的DAO和表。以下是我的版本。gradle代码 它取自github链接https://github.com/jklingsporn/vertx-jooq/tree/master/vertx-jooq-classic-jdbc 但是当我运行commmand时/gradlew jooqGenerate要生成代码,它

  • 我在mac os中使用pip安装opencv python。现在是cv2。imshow函数给出以下错误 OpenCV错误:未指定的错误(函数未实现。使用Windows、GTK 2. x或Carbon支持重建库。如果你在Ubuntu或Debian上,安装libgtk2.0-dev和pkg-config,然后在cvShowImage中重新运行cmake或配置脚本) 我如何解决这个问题?为什么pip不检