简体   繁体   English

用Python方式计算列表中特定邻居的方法

[英]Pythonic way to count specific neighbors in a list

I have a list. 我有一个清单。 For example: 例如:

[0, 0, 1, 0, 0, 1, 0] [0,0,1,0,0,1,0]

I'd like to know what is the most effective way to count the 1 -> 0 transitions. 我想知道计数1-> 0转换的最有效方法是什么。 In this case for example the answer is 2 (in the 2-3 and in the 5-6 positions) 例如,在这种情况下,答案是2(在2-3和5-6位置)

I tried the following: 我尝试了以下方法:

 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)])

I'm wondering if there is a better way 我想知道是否有更好的方法

Here are 3 ways: 这是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

Explanation 说明

  1. First method utilises sum with a generation expression and zip to loop pairwise elements. 第一种方法利用带有生成表达式的sumzip来循环成对元素。
  2. Second method is similar to the first but performs better as it avoids building a second list explicitly. 第二种方法与第一种方法相似,但性能更好,因为它避免显式构建第二种列表。
  3. Third method utilises the 3rd party numpy library and is a vectorised approach. 第三种方法利用了第三方numpy库,是一种矢量化方法。

Transforming your input data with slices and zips and cuts and folds is one way to approach it. 使用切片,拉锁,切割和折叠来转换输入数据是一种处理方法。 And it's awesome to see how these generic actions can be combined to build a machine that represents our intended action, even if it arrives at the desired result in a roundabout way. 而且,很高兴看到如何将这些通用动作组合起来,以构成代表我们预期动作的机器,即使它以回旋的方式达到了预期的结果。

However, I think a more direct approach yields a more natural program. 但是,我认为更直接的方法会产生更自然的程序。 You can express your intention using natural descriptors and operations. 您可以使用自然的描述符和操作表达您的意图。 Another benefit is you can more clearly visualize the space-time requirements of the process your function creates. 另一个好处是您可以更清晰地可视化函数创建过程的时空需求。 Ie, it's easy to see switches below runs in O(n) ; 即,很容易看到下面的switchesO(n)中运行; comparatively, it's very hard to estimate space-time requirements of the "machine" implementation. 相比较而言,很难估计“机器”实现的时空需求。

A simple recursive function 一个简单的递归函数

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 :(

Above, the answer is 4 because it's counting switches from 0 to 1 and switches from 1 to 0. You only want to count switches in one direction. 上面的答案是4因为它正在计数从0到1的开关, 并且从1到0的开关。您只想在一个方向上计数开关。 We could modify our function like this 我们可以这样修改我们的功能

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 :)

But you can see there's a clever way to condense the conditional 但是您可以看到有一种巧妙的方法可以压缩条件

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 :)

You can use sum : 您可以使用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))

Output: 输出:

2

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM