递归-Python-为什么print(Foo)显示的内容不同于print(FunctionReturningFoo())

时间:2019-02-01 13:31:10

标签: python recursion

为什么print(foo)显示的内容不同于print(functionreturningthesame())

查看输出,在函数中打印数组将显示正确答案,但不会打印函数的返回。我可能对递归迭代感到困惑...

def AreNotOpposite(a,b):
  if a == "NORTH" and b == "SOUTH":
    return False
  if a == "SOUTH" and b == "NORTH":
    return False
  if a == "WEST" and b == "EAST":
    return False
  if a == "EAST" and b == "WEST":
    return False
  return True

def canBeBetter(arr):
  for i in range(len(arr)-1):
    if not AreNotOpposite(arr[i],arr[i+1]):
      return True
  return False

def dirReduc(arr):
  re = []
  avoid = -1
  for i in range(len(arr)):
    if avoid == i:
      continue
    if i+1 == len(arr):
      re.append(arr[i])
    elif AreNotOpposite(arr[i],arr[i+1]):
      re.append(arr[i])
    else: #do not append neither the nextone
      avoid = i+1
  if canBeBetter(re):  #can reduce more?
    dirReduc(re)
  else:
    print(re)
    return re

print (dirReduc(['NORTH', 'WEST', 'EAST','SOUTH', 'NORTH','SOUTH','EAST','NORTH']))

输出:

['EAST', 'NORTH']
None

3 个答案:

答案 0 :(得分:1)

我想你想要这样的东西

  if canBeBetter(re):  #can reduce more?
    return dirReduc(re)
  else:
    return re

答案 1 :(得分:1)

您需要返回递归调用的结果(否则,您的函数将触及逻辑的结尾并仅返回None):

if canBeBetter(re):  #can reduce more?
  return dirReduc(re)
else:
  print(re)
  return re

答案 2 :(得分:0)

在罗马时...

递归是一种功能性遗产,因此将其与功能性样式一起使用可产生最佳效果。这意味着要避免像re.append (...)这样的突变,避免像avoid这样的重新分配,以及像print这样的其他副作用。这也意味着避免for,这是循环的必要构造。递归是我们在函数样式中循环的方式,所以让我们使用函数样式。

要解决此问题,我们将把输入视为队列q,并且将使用堆栈s构造输出。

  1. 如果队列(输入)为空,则堆栈(输出)已完全构建。返回反转的堆栈。

  2. (归纳式:q不为空)

    如果堆栈为空,则将队列中的第一项推入堆栈。重复。

  3. (归纳法:q不为空,s不为空)

    每个元素至少包含一个元素。如果每个元素的第一个元素均为opposite,则将其删除。重复。

  4. (归纳式:q不为空,s不为空,元素也不为opposite

    将队列中的元素推入堆栈。重复。

这是我们用Python编写的方式-

def dir (q, s = []):
  if not q:                   # 1
    return s[::-1]
  elif not s:                 # 2
    return dir \
      ( q[1:]
      , [q[0]] + s
      )
  elif opposite (s[0], q[0]): # 3
    return dir \
      ( q[1:]
      , s[1:]
      )
  else:                       # 4
    return dir \
      ( q[1:]
      , [q[0]] + s
      )

我们可以将opposite定义为-

def opposite (a, b, flipped = False):
  if a == "NORTH" and b == "SOUTH":
    return True
  elif a == "EAST" and b == "WEST":
    return True
  elif flipped:
    return False
  else:
    return opposite (b, a, True)

测试-

print (dir (['NORTH', 'WEST', 'EAST','SOUTH', 'NORTH','SOUTH','EAST','NORTH']))
# ['EAST', 'NORTH']

提高一致性和可读性

Python使用[...]语法访问数组元素,但我确实认为它们会损害可读性。考虑这些助手-

def first (xs = []):
  return xs[0]

def rest (xs = []):
  return xs[1:]

def reverse (xs = []):
  return xs[::-1]

由于一致地应用了功能样式,我们的程序的可读性得到了极大提高-

def dir (q, s = []):
  if not q:
    return reverse(s)
  elif not s:
    return dir \
      ( rest(q)
      , [first(q)] + s
      )
  elif opposite (first(s), first(q)):
    return dir \
      ( rest(q)
      , rest(s)
      )
  else:
    return dir \
      ( rest(q)
      , [first(q)] + s
      )

最后,[...] + ...使用了一个前缀+运算符,它也是样式不一致的地方。函数风格与函数有关,因此,我们将使用函数-

def push (x, xs = []): # immutable push
  return [ x ] + xs

def dir (q, s = []):
  if not q:
    return reverse(s)
  elif not s:
    return dir \
      ( rest(q)
      , push(first(q), s)
      )
  elif opposite (first(s), first(q)):
    return dir \
      ( rest(q)
      , rest(s)
      )
  else:
    return dir \
      ( rest(q)
      , push(first(q), s)
      )

查看此程序并在您自己的浏览器中验证结果:repl.it