Pythonic计算列表中特定邻居的方法

时间:2018-04-05 20:02:11

标签: python python-3.x list counting

我有一份清单。例如:

  

[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 个答案:

答案 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

<强>解释

  1. 第一种方法使用带有生成表达式的sumzip来循环成对元素。
  2. 第二种方法与第一种方法类似,但效果更好,因为它避免明确构建第二个列表。
  3. 第三种方法使用第三方numpy库,是一种矢量化方法。

答案 1 :(得分:1)

使用切片和拉链以及切割和折叠来转换输入数据是接近它的一种方法。看到如何将这些通用操作组合起来构建一个代表我们预期行动的机器,即使它以迂回的方式达到预期的结果,这真是太棒了。

但是,我认为更直接的方法会产生更自然的方案。您可以使用自然描述符和操作来表达您的意图。另一个好处是,您可以更清晰地显示您的功能创建的过程的时空要求。也就是说,很容易看到下面的switchesO(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