在Python上返回None

时间:2018-03-06 20:44:44

标签: python python-3.x return

我的学生正在为课堂制作摇滚,纸张,剪刀模拟。一个组有一个错误,其中一个函数不会返回任何东西。我已检查过它,看看所有分支机构是否都有退货声明,而且确实如此。我也试过了一个可视化工具,功能就此停止了,我不知道为什么。

def Win_Loss(my_history, their_history):
    if len(my_history) > 1 and len(their_history) > 1:
        if (their_history[-1] == 's' and my_history[-1] == 'r'):
            return 'p'

    elif len(my_history) > 1 and len(their_history) > 1:
        if (their_history[-1] == 'r' and my_history[-1] == 'p'):
            return 's'

    elif len(my_history) > 1 and len(their_history) > 1:
        if (their_history[-1] == 'p' and my_history[-1] == 's'):
            return 'r'

    elif len(my_history) > 1 and len(their_history) > 1:
        if (their_history[-1] == 's' and my_history[-1] == 'p'):
            return 'r'

    elif len(my_history) > 1 and len(their_history) > 1:
        if (their_history[-1] == 'r' and my_history[-1] == 's'):
            return 'p'

    elif len(my_history) > 1 and len(their_history) > 1:
        if (their_history[-1] == 'p' and my_history[-1] == 'r'):
            return 's'

    elif len(my_history) > 1 and len(their_history) > 1:
        if (their_history[-1] == 's' and my_history[-1] == 's'):
            return 'r'

    elif len(my_history) > 1 and len(their_history) > 1:
        if (their_history[-1] == 'r' and my_history[-1] == 'r'):
            return 'p'

    elif len(my_history) > 1 and len(their_history) > 1:
        if (their_history[-1] == 'p' and my_history[-1] == 'p'):
            return 's'
    else:
        return "p"
print(Win_Loss(['s','p','p'],['s','p','p']))

这应该是打印',但它打印无。

3 个答案:

答案 0 :(得分:3)

如果任何内部if失败,它将返回None,因为外部的if / elif被占用,因此else:块将不会被执行。

要明确的是,它们的整个功能相当于:

def Win_Loss(my_history, their_history):
    if len(my_history) > 1 and len(their_history) > 1:
        if (their_history[-1] == 's' and my_history[-1] == 'r'):
            return 'p'
    else:
        return "p"

因为一旦获得第一个if,就无法获取所有其他elif。由于它们具有相同的条件,因此永远不会达到所有elif

如果您取消else:,只是默认return "p",则会保证返回值:

elif len(my_history) > 1 and len(their_history) > 1:
    if (their_history[-1] == 'p' and my_history[-1] == 'p'):
        return 's'
# If anything else happens
return "p"

但这并不能解决根本问题。

或者,他们可以结合条件:

if len(my_history) > 1 and len(their_history) > 1 and
    (their_history[-1] == 's' and my_history[-1] == 'r'):
        return 'p'

这也可以避免这个问题,因为没有内部条件可以跳过返回,else:将按预期工作。

正如其他人所提到的,整个外部if块是多余的。对于我的女孩(我教11-13岁/年),我建议他们将默认返回到顶部...然后你不必检查每个人是否足够大:

if not (len(my_history) > 1 and len(their_history) > 1):
    return "p"  # default value
elif their_history[-1] == 's' and my_history[-1] == 'r':
    return 'p'
elif their_history[-1] == 'r' and my_history[-1] == 'p':
    return 's'
elif their_history[-1] == 'p' and my_history[-1] == 's':
    return 'r'
elif their_history[-1] == 's' and my_history[-1] == 'p':
    return 'r'
elif their_history[-1] == 'r' and my_history[-1] == 's':
    return 'p'
elif their_history[-1] == 'p' and my_history[-1] == 'r':
    return 's'
elif their_history[-1] == 's' and my_history[-1] == 's':
    return 'r'
elif their_history[-1] == 'r' and my_history[-1] == 'r':
    return 'p'
elif their_history[-1] == 'p' and my_history[-1] == 'p':
    return 's'

如果我们失败,最后会添加一个例外:

raise AssertionError, "a combination not covered was encountered"

然后会确保我们知道我们是否忘记了这种可能性。

根据他们的能力,可能会或可能不值得讨论的其他风格点:

通过嵌套他们的条件,他们可以减少重复,但如果他们想要调整他们的机器人这是一个障碍而不是一个好处。

if not len(my_history) > 1 and len(their_history) > 1:
    return "p"  # default value

elif their_history[-1] == 's':  # if they threw scissors
    if my_history[-1] == 'r':       # and I threw rock
        return 'p'                      # throw paper
    return 'r'                      # otherwise throw rock

elif their_history[-1] == 'r':
    if my_history[-1] == 'p':
        return 's'
    return 'p'

elif their_history[-1] == 'p': 
    if my_history[-1] == 's':
        return 'r'
    return 's'

答案 1 :(得分:3)

您的elif语句处于错误的级别as explained by @SiongThyeGoh。以下工作正常,尽管不是很优秀。

def Win_Loss(my_history, their_history):
    if len(my_history) > 1 and len(their_history) > 1:
        if (their_history[-1] == 's' and my_history[-1] == 'r'):
            return 'p'
        elif (their_history[-1] == 'r' and my_history[-1] == 'p'):
            return 's'
        ...

但这将是我最喜欢的解决方案:

def Win_Loss(my_history, their_history):

    d = {frozenset({'s', 'r'}): 'p',
         frozenset({'r', 'p'}): 's',
         frozenset({'s', 'p'}): 'r',
         frozenset({'s', 's'}): 'r',
         frozenset({'r', 'r'}): 'p',
         frozenset({'p', 'p'}): 's'}

    if len(my_history) > 1 and len(their_history) > 1:
        return d.get(frozenset({their_history[-1], my_history[-1]}))

    else:
        return "p"

print(Win_Loss(['s','p','p'],['s','p','p']))

答案 2 :(得分:0)

if len(my_history) > 1 and len(their_history) > 1:
        if (their_history[-1] == 's' and my_history[-1] == 'r'):
            return 'p'

看看前三行,如果第一个if条件满足但第二个不满足,则不返回任何内容,即得到None。

如果这种情况通过:

if len(my_history) > 1 and len(their_history) > 1:

然后它将进入前三行,否则,另一个elif语句将被忽略,因为它是相同的条件,它只会到达else部分并返回p。

它只能返回p或None。