【问题标题】:Better way to split list of integers based on values and rules根据值和规则拆分整数列表的更好方法
【发布时间】:2019-09-12 06:26:06
【问题描述】:

目标是根据以下规则,根据每个元素的邻居拆分整数列表:

  • (当前/焦点值小于等于上一个)和(当前值等于下一个),即prev_value >= focal_value == next_value

  • (当前值小于上一个)和(当前值小于下一个),即prev_value > focal_value < next_value

为了说明,给定x产生y

x = (1, 4, 2, 1, 4, 2, 4, 1, 4, 1, 4, 4, 3)
y = [[1, 4, 2], [1, 4], [2, 4], [1, 4], [1, 4, 4, 3]]
assert func(x) == y

我试过了:

def per_window(sequence, n=1):
    """
    From http://stackoverflow.com/q/42220614/610569
        >>> list(per_window([1,2,3,4], n=2))
        [(1, 2), (2, 3), (3, 4)]
        >>> list(per_window([1,2,3,4], n=3))
        [(1, 2, 3), (2, 3, 4)]
    """
    start, stop = 0, n
    seq = list(sequence)
    while stop <= len(seq):
        yield tuple(seq[start:stop])
        start += 1
        stop += 1


def func(x):
    result = []
    sub_result = [x[0]]
    for prev_value, focal_value, next_value in per_window(x, 3):
        # These if and elif cases trigger syllable break.
        if prev_value >= focal_value == next_value:
            sub_result.append(focal_value)
            result.append(sub_result)
            sub_result = []
        elif prev_value > focal_value < next_value:
            result.append(sub_result)
            sub_result = []
            sub_result.append(focal_value)
        else: # no  break
            sub_result.append(focal_value)
    sub_result.append(next_value)
    result.append(sub_result)
    return result


x = (1, 4, 2, 1, 4, 2, 4, 1, 4, 1, 4, 4, 3)
y = [[1, 4, 2], [1, 4], [2, 4], [1, 4], [1, 4, 4, 3]]

assert func(x) == y

但我的问题是:

  • 如果我们仔细查看 if 和 elif “案例”,看起来第一个 if 永远不会被捕获,因为第二个 if 会先到达。那正确吗?第一个if 案例将启动的示例有哪些?

  • 有没有更好的方法来实现基于规则拆分子列表的相同目标?

  • 最后两个追加需要存在于per_window的循环之外,这些扼杀者叫什么?有没有办法不这样做循环?

【问题讨论】:

    标签: python list loops integer sublist


    【解决方案1】:
    1. 在您的示例中,第一个 if 永远不会被触发。但它将与此示例数据一起使用:

      x = (5 ,4, 4, 2)
      y = [[5, 4], [4, 2]]
      
    2. 更好是相当主观的。但是不使用windows也可以达到同样的目标,只需要改变值

      def func2(x):
          x = iter(x)
          try:
              prev_value = next(x)
              focal_value = next(x)
          except StopIteration:
              return [list(x)]
          sub_result = [prev_value]
          result = [sub_result]
          for next_value in x:
              if prev_value >= focal_value == next_value:
                  sub_result.append(focal_value)
                  sub_result = []
                  result.append(sub_result)
              elif prev_value > focal_value < next_value:
                  sub_result = [focal_value]
                  result.append(sub_result)
              else:
                  sub_result.append(focal_value)
              prev_value, focal_value = focal_value, next_value
          sub_result.append(focal_value)
          return result
      

      timeit 说它快两倍以上

    3. 一旦你持有循环中的最后一个值,你就必须在循环之后为它添加特殊处理。但我的代码显示可以在循环内附加sub_result 列表。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-01-30
      • 1970-01-01
      • 2020-03-11
      • 1970-01-01
      • 2013-02-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多