【问题标题】:True/false statements within if statements and for loopsif 语句和 for 循环中的真/假语句
【发布时间】:2018-07-31 15:12:15
【问题描述】:

我在一个列表中有多个列表,并且想要检查多个内容并使用if 条件和TrueFalse 形成一个新列表。我的代码:

import re
runlist = [['229', '134', '9'], ['229', '137', '5'], ['629', '140', '5'], ['631', '140', '5'], ['632', '140', '5'], ['633', '140', '8'], ['422', '141', '5'], ['628', '141', '9'], ['629', '141', '11']], [['629', '145', '8'], ['630', '145', '8'], ['631', '145', '8'], ['632', '145', '8'], ['632', '146', '5']], ...]
goodrunslist = []
for i in range(len(runlist)):
    for k in range (0, len(runlist[i])):
        if re.match('[2][0-5][0-9]', runlist[i][k][0]):
            ch2 = True
    for m in range (0, len(runlist[i])):
        if re.match('[6][0-4][0-9]', runlist[i][m][0]):
            ch4 = True
    if ch2 and ch4:
        goodrunslist.append(runlist[i])

但是,在最后的第一个 for 循环下,它给了我一个 NameError ch2ch4 未定义,因此它不能将任何内容附加到新列表中。我该如何解决这个问题?

编辑:我已经通过下面的代码修复了NameError,但现在我的问题是新列表没有返回任何内容(它正在返回[]),即使我可以看到它应该有一些其中的元素。新代码如下。任何修复或建议表示赞赏;谢谢!

import re
runlist = [['229', '134', '9'], ['229', '137', '5'], ['629', '140', '5'], ['631', '140', '5'], ['632', '140', '5'], ['633', '140', '8'], ['422', '141', '5'], ['628', '141', '9'], ['629', '141', '11']], [['629', '145', '8'], ['630', '145', '8'], ['631', '145', '8'], ['632', '145', '8'], ['632', '146', '5']], ...]
goodrunslist = []
ch2, ch4 = False, False
for i in range(len(runlist)):
    for k in range (0, len(runlist[i])):
        if re.match('[2][0-5][0-9]', runlist[i][k][0]):
            ch2 = True
        else:
            ch2 = False
    for m in range (0, len(runlist[i])):
        if re.match('[6][0-4][0-9]', runlist[i][m][0]):
            ch4 = True
        else:
            ch4 = False
    if ch2 and ch4:
        goodrunslist.append(runlist[i])

【问题讨论】:

  • 您需要将这些变量初始化为内部循环上方的False,以便无论是否找到任何匹配项,它们都具有定义的值。
  • 您应该接受一个解决了您的第一个问题的答案。然后,您针对新错误发布一个新问题。
  • ch2 and ch4 永远不会是真的。您的号码不能以 2 6 开头
  • 这里的括号不匹配,所以这段代码根本不会运行(我只是删除了,...。但我成功添加了[['629', '245', '8'], ['245', '245', '8']]

标签: python list boolean append nameerror


【解决方案1】:

在这一行:

if ch2 and ch4:

您在第一个 for 循环的范围内引用了 ch2ch4,但它们是在内部 for 循环的范围内定义的。为了解决这个问题,首先在第一个 for 循环的范围内声明它们,方法是添加以下行:

ch2, ch4 = False, False

在你的第一个 for 循环开始的下方。

更新:我建议更实用地执行此操作。这避免了使用突变创建局部变量。它还避免了嵌套循环和 ifs。这是编写代码的另一种方法:

# This function checks each list within the list to see if it should belong in goodrunslist
def checkRunListItem(runListItem):
      # this generator takes each item in the list and turns it into the boolean that your if statement
      # would use to decide to return true or false

      # any checks if any item in a list is true
      ch2 = any(re.match('[2][0-5][0-9]', item[0]) for item in runListItem)
      ch4 = any(re.match('[6][0-4][0-9]', item[0]) for item in runListItem)
      return ch2 and ch4
goodrunslist = filter(checkRunListItem, runlist)

但是,您的条件似乎很奇怪,我不确定您要达到什么目的。您在示例中提供的列表的括号不匹配。如果该项目是列表列表的列表,其中基本列表中列表的第一个元素至少与每个正则表达式匹配,则此代码只会将项目添加到 goodrunslist。您能否更具体地说明您要解决的问题?

【讨论】:

  • 谢谢,我在第一个循环上方将它们中的每一个都定义为False。但是我在循环中添加了另一个条件:for l in range (0, len(runlist[i])): if re.match('^[4][0-5][0-9]$', runlist[i][l][0]): ch3 = True print ch3,现在它告诉我ch3True,尽管我可以清楚地看到这是不对的。你知道为什么会这样吗?
  • 一旦你将它设置为True,一旦它保持为真。我建议以更实用/pythonic 的方式执行此操作,以避免这样的混淆。
  • 响应您的编辑,您所描述的实际上正是我想要实现的。我如何使用上面的代码将每个对应的列表列表添加到新的 goodrunslist 列表中?
  • 对不起,我把return留在那里,而不是把它分配给列表。 filter 获取一个列表并创建一个包含满足条件的项目的新列表。对于您的用例来说,这是一个不错的选择。
  • any(re.match('[2][0-5][0-9]', item[0]) for item in runListItem) 看起来会更干净
【解决方案2】:

您的内部循环在完全相同的范围内,并且您对列表的索引相同,因此可以组合它们。

此外,您不需要range(),因为您可以直接遍历对象。

更重要的是,您正在检查列表的第一个元素(都是三个数字)以查看它们是否匹配 both 正则表达式,这永远不会是真的(数字不能以26 开头)。我认为您的意思是使用or

import re
runlist = [[['229', '134', '9'], ['229', '137', '5'], ['629', '140', '5'], ['631', '140', '5'], ['632', '140', '5'], ['633', '140', '8'], ['422', '141', '5'], ['628', '141', '9'], ['629', '141', '11']], [['629', '145', '8'], ['630', '145', '8'], ['631', '145', '8'], ['632', '145', '8'], ['632', '146', '5']]]
goodrunslist = []
for run in runlist:
    ch2, ch4 = False, False
    for r in run:
        ch2 = re.match('2[0-5][0-9]', r[0])
        ch4 = re.match('6[0-4][0-9]', r[0])
    if ch2 or ch4:
        goodrunslist.append(run)
print(goodrunslist)

但是,我认为这里的缩进是关闭的。您仅在扫描完所有i in len(runlist[i])val in run 之后 附加。所以,条件只适用于runlist的最后一个元素

解决方案是进行检查并添加内部列表,而不是完整的运行列表

goodrunslist = []
for run in runlist:
    for r in run:
        ch2 = bool(re.match('2[0-5][0-9]', r[0]))
        ch4 = bool(re.match('6[0-4][0-9]', r[0]))
        if ch2 or ch4:
          goodrunslist.append(r)
print(goodrunslist)

【讨论】:

    猜你喜欢
    • 2013-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-16
    • 2019-06-09
    相关资源
    最近更新 更多