【问题标题】:What is common pratice with return statements in functions?函数中返回语句的常见做法是什么?
【发布时间】:2020-05-07 19:59:54
【问题描述】:

我不知道何时使用return 函数。在下面的函数中,我的直觉是 return 语句应该在那里返回修改后的列表,但我的 TA 说这是多余的,我不太明白为什么。任何关于何时正确使用return 声明和常见做法的说明将不胜感激。

p = [2,0,1]
q = [-2,1,0,0,1,0,0,0]
p1 = [0,0,0,0]

#Without return statement
def drop_zeros1(p_list):
    """drops zeros at end of list"""
    i = 0 
    while i < len(p_list):
            if p_list[-1]==0:
                p_list.pop(-1)
            else:
                break

#With return statement
def drop_zeros(p_list):
    """drops zeros at end of list"""
    i = 0 
    while i < len(p_list):
            if p_list[-1]==0:
                p_list.pop(-1)
            else:
                return p_list
                break

还有为什么在列表p1上使用时输出不一致,它只在应该删除所有零时才删除最后一个0?

非常感谢,

【问题讨论】:

  • 一旦遇到非零值,这两个函数都会停止迭代。
  • 如果你在上一行返回,第二次休息是没有意义的
  • 这就是重点,所以当 p1 被传递给函数时,它应该返回一个空列表
  • 列表也在函数范围内被修改,所以除非你想让函数实际输出一些东西,否则return 是多余的
  • 惯例是改变一个参数并返回None 返回一个新值,保持参数不变,而不是两者。

标签: python list return


【解决方案1】:

惯例是函数要么改变给它的参数,要么返回结果,但不改变参数。

这是为了防止你的函数的用户这样做:

template = [1, 2, 0, 0]
shorter = drop_zeros(template)
print ("input was ", template, " and output was ", shorter)

他们会期待这样的输出:

输入为 [1, 2, 0, 0],输出为 [1, 2]

...但惊讶地看到:

输入为 [1, 2],输出为 [1, 2]

所以为了避免这种情况,你可以要么

  • 不返回修改后的参数,而是返回None。这样上面的代码就会输出...and output was None,用户就会明白这个函数并不是为了返回结果而设计的。

  • 返回结果,但确保参数保留其原始内容

所以在你的情况下你可以这样做:

def drop_zeros(p_list):
    """drops zeroes at end of list, in-place"""
    while p_list and p_list[-1] == 0:
        p_list.pop()

请注意,else 可以更好地集成到 while 条件中。不再需要明确的break.pop() 也不需要 -1 作为参数:它是默认值。

如果你更喜欢返回结果的函数,那么逻辑应该有些不同:

def drop_zeros(p_list):
    """returns a copy of the list without the ending zeroes"""
    for i in range(len(p_list)-1, -1, -1):
         if p_list[i] != 0:
             return p_list[0:i+1]
    return []

现在代码的设计目的是:

template = [1, 2, 0, 0]
shorter = drop_zeros(template)
print ("input was ", template, " and output was ", shorter)
# input was [1, 2, 0, 0] and output was [1, 2]

【讨论】:

  • 感谢您的深入解释,非常感谢您花费的时间和精力,现在您将用户示例放在顶部对我来说真的很清楚。
【解决方案2】:

你的 TA 是对的,返回是多余的,因为在 python 中称为 aliasing

基本上,在您的函数中,p_list 是对您在调用函数时传入的任何列表的引用(不是副本)。由于您使用pop,它在提取元素时就地改变列表,p_list 将被修改,并且此修改将在函数外部可见:

drop_zeros(q) # from here, in the function, p_list is q (as in, exactly the same object)
print(q)

打印

[-2,1,0,0,1]

【讨论】:

  • 好的,感谢您澄清为什么它是多余的。附带说明一下,打印应该是 [2,0,1],因为该函数假定删除列表末尾的所有零,直到遇到非零。
  • 啊,我没有阅读文档字符串(或pop 之外的代码)。我会改变例子;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-16
  • 2010-10-16
  • 2015-03-14
  • 1970-01-01
  • 1970-01-01
  • 2011-07-16
相关资源
最近更新 更多