我有一份清单。例如:
[0,0,1,0,0,1,0]
我想知道计算 1 - >的最有效方法是什么? 0 过渡。在这种情况下,例如答案是2(在2-3和5-6位置)
我尝试了以下内容:
stat=[0, 0, 1, 0, 0, 1, 0]
pair1=stat[:-1]
pair2=stat[1:]
result=len([i for i in zip(pair1, pair2) if i==(1,0)])
我想知道是否有更好的方法
答案 0 :(得分:2)
以下是3种方式:
from itertools import islice
import numpy as np
lst = [0, 0, 1, 0, 0, 1, 0]
res1 = sum(i - j == 1 for i, j in zip(lst, lst[1:])) # 2
res2 = sum(i - j == 1 for i, j in zip(lst, islice(lst, 1, None))) # 2
res3 = np.sum(np.diff(lst) == -1) # 2
<强>解释强>
sum
和zip
来循环成对元素。numpy
库,是一种矢量化方法。答案 1 :(得分:1)
使用切片和拉链以及切割和折叠来转换输入数据是接近它的一种方法。看到如何将这些通用操作组合起来构建一个代表我们预期行动的机器,即使它以迂回的方式达到预期的结果,这真是太棒了。
但是,我认为更直接的方法会产生更自然的方案。您可以使用自然描述符和操作来表达您的意图。另一个好处是,您可以更清晰地显示您的功能创建的过程的时空要求。也就是说,很容易看到下面的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.您只想计算 1中的开关方向。我们可以修改我们的功能
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 :)
答案 2 :(得分:0)
您可以使用sum
:
s = [0, 0, 1, 0, 0, 1, 0]
new_s = sum(abs(s[i]-s[i+1]) == 1 for i in range(0, len(s)-1, 2))
输出:
2