if语句和for循环中的真/假语句

时间:2018-02-21 06:05:04

标签: python list boolean append nameerror

我在列表中有多个列表,并希望检查多个内容并形成包含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])

2 个答案:

答案 0 :(得分:0)

在这一行:

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添加项目,其中基本列表中列表的第一个元素与每个正则表达式至少有一个匹配项。你能更具体地解决你想要解决的问题吗?

答案 1 :(得分:0)

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

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

更重要的是,您正在检查列表的第一个元素(全部是三位数)以查看它们是否与两个正则表达式相匹配,这些正则表达不会是真的(数字可以& #39; t以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)