为什么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
答案 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
构造输出。
如果队列(输入)为空,则堆栈(输出)已完全构建。返回反转的堆栈。
(归纳式:q
不为空)
如果堆栈为空,则将队列中的第一项推入堆栈。重复。
(归纳法:q
不为空,s
不为空)
每个元素至少包含一个元素。如果每个元素的第一个元素均为opposite
,则将其删除。重复。
(归纳式: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