[英]Pythonic way to count specific neighbors in a list
我有一个清单。 例如:
[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)])
我想知道是否有更好的方法
这是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
库,是一种矢量化方法。 使用切片,拉锁,切割和折叠来转换输入数据是一种处理方法。 而且,很高兴看到如何将这些通用动作组合起来,以构成代表我们预期动作的机器,即使它以回旋的方式达到了预期的结果。
但是,我认为更直接的方法会产生更自然的程序。 您可以使用自然的描述符和操作表达您的意图。 另一个好处是您可以更清晰地可视化函数创建过程的时空需求。 即,很容易看到下面的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 :)
您可以使用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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.