使用切片、拉链、切割和折叠来转换您的输入数据是处理它的一种方法。很高兴看到如何将这些通用动作结合起来构建一个代表我们预期动作的机器,即使它以迂回的方式达到预期的结果。
但是,我认为更直接的方法会产生更自然的程序。您可以使用自然描述符和操作来表达您的意图。另一个好处是您可以更清楚地可视化您的函数创建的过程的时空需求。即,很容易看到下面的switches 在O(n) 中运行;相比之下,很难估计“机器”实现的时空需求。
一个简单的递归函数
def switches (iter, last = 0):
if not iter:
return 0
first, *rest = iter
if first == last:
return switches (rest, last)
else:
return 1 + switches (rest, first)
print (switches ([ 0, 0, 1, 1, 0, 0, 1, 1, 1, 0 ]))
# 4 :(
上面的答案是4,因为它正在计数从 0 到 1 的开关并且 从 1 到 0 的开关。您只想计算 一个 方向的开关。我们可以像这样修改我们的函数
def switches (iter, last = 0):
if not iter:
return 0
first, *rest = iter
if first == last:
return switches (rest, last)
else:
if first == 1: # only count when switching from 1
return 1 + switches (rest, first)
else:
return 0 + switches (rest, first)
print (switches ([ 0, 0, 1, 1, 0, 0, 1, 1, 1, 0 ]))
# 2 :)
但是你可以看到有一个巧妙的方法来压缩条件
def switches (iter, last = 0):
if not iter:
return 0
first, *rest = iter
if first == last:
return switches (rest, last)
else:
return first + switches (rest, first)
print (switches ([ 0, 0, 1, 1, 0, 0, 1, 1, 1, 0 ]))
# 2 :)