【问题标题】:Pythonic way to count specific neighbors in a listPythonic 计算列表中特定邻居的方法
【发布时间】:2018-04-06 16:28:54
【问题描述】:

我有一个清单。例如:

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

我想知道是否有更好的方法

【问题讨论】:

  • 您能否展示您的尝试,并准确描述您遇到的问题?

标签: python python-3.x list counting


【解决方案1】:

这里有 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. 第一种方法利用 sum 和生成表达式和 zip 循环成对元素。
  2. 第二种方法与第一种方法类似,但性能更好,因为它避免了显式构建第二个列表。
  3. 第三种方法利用第 3 方 numpy 库,是一种矢量化方法。

【讨论】:

  • 漂亮、简短、优雅的解决方案
【解决方案2】:

使用切片、拉链、切割和折叠来转换您的输入数据是处理它的一种方法。很高兴看到如何将这些通用动作结合起来构建一个代表我们预期动作的机器,即使它以迂回的方式达到预期的结果。

但是,我认为更直接的方法会产生更自然的程序。您可以使用自然描述符和操作来表达您的意图。另一个好处是您可以更清楚地可视化您的函数创建的过程的时空需求。即,很容易看到下面的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 的开关。您只想计算 一个 方向的开关。我们可以像这样修改我们的函数

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

【讨论】:

    【解决方案3】:

    你可以使用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
    

    【讨论】:

      猜你喜欢
      • 2011-10-07
      • 2018-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多