在列表上映射布尔函数

时间:2017-06-20 11:08:39

标签: python

我是编程的新手,所以这可能是一个愚蠢的问题!

我正在尝试编写一个函数,该函数采用字母等级列表并返回布尔值true或false,具体取决于它是否为合格等级

## Calculate total units passed

def unitPassed(letterGrade):
    if letterGrade == 'N':
        passed = False
    else:
        if letterGrade == 'NCN':
           passed = False
        else:
            if letterGrade == 'WN':
                passed = False
            else:
                True
    return passed

unitsPassed = map(unitPassed,courseGradeLetter)

我试图通过创建一个测试成绩是否为成绩等级的函数来做到这一点,然后将其映射到成绩列表上。

问题是,对于包含多个元素的列表,我收到以下错误:

local variable 'passed' referenced before assignment

如果我尝试使用包含一个元素的列表,我会得到正确的结果。

为什么会这样?

感谢。

-

谢谢大家,你的回答给了我很多帮助!

4 个答案:

答案 0 :(得分:4)

有些人已经指出了你的错误并发布了最多的pythonic解决方案,但无论如何 - 这是另一个代码审查,但这次是一步一步:

第一点:学会使用elif而不是在if子句中嵌套else子句:

def unitPassed(letterGrade):
    if letterGrade == 'N':
        passed = False
    elif letterGrade == 'NCN':
        passed = False
    elif letterGrade == 'WN':
        passed = False
    else:
        passed = True
    return passed

正如您所看到的,这已经更具可读性了。

第二点:在Python中我们赞成"早期回报" - 即,在这种测试中,我们不是在所有分支中设置变量并在最后返回它,而是直接返回(这避免了elif / else链等):

def unitPassed(letterGrade):
    if letterGrade == 'N':
        return False
    if letterGrade == 'NCN':
        return False
    if letterGrade == 'WN':
        return False
    return True

这使代码更加直截了当。

当然最后的重构是尽可能避免多次测试,如Dadep和digitake发布的那样(但是使用元组而不是列表,因为我们不需要列表的开销):

def unitPassed(letterGrade):
    return letterGrade not in ("N", "NCN", "WN")

此外,您在代码段中使用map()map()仍然完全有效且适当,此处更惯用(并且速度更快)的版本将是列表理解:

passed = [unitPassed(letter) for letter in courseGradeLetter]

由于unitPassed现在基本上是一个简单的短表达式,你可以内联它(除非你在其他地方需要这个函数):

passed = [letter not in ('N', 'NCN', 'NWN') for letter in courseGradeLetter]

答案 1 :(得分:2)

这个怎么样

def unitPassed(letterGrade):
    return letterGrade not in ['N', 'NCN', 'WN']

unitsPassed = map(unitPassed,courseGradeLetter)

答案 2 :(得分:0)

您可以将您的功能重新定义为:

>>> def unitPassed(letterGrade):
...     GP=['N', 'NCN', 'WN']
...     if letterGrade in GP:
...         return False
...     return True
... 
>>> letterGrade='DE'
>>> unitPassed(letterGrade)
True
>>> letterGrade='NCN'
>>> unitPassed(letterGrade)
False

答案 3 :(得分:0)

错误出现在第三个else语句中,即第13行 将True更改为passed = True

此外,您可以使您的功能干净,

def unitPassed(letterGrade):
    if letterGrade == 'N':
        passed = False
    elif letterGrade == 'NCN':
        passed = False
    elif letterGrade == 'WN':
        passed = False
    else:
        passed = True
    return passed