【问题标题】:Pythonic way of finding where a value is in a list of ranges查找值在范围列表中的位置的 Pythonic 方法
【发布时间】:2019-07-27 13:29:31
【问题描述】:

我有一个开始和结束值字典的列表:

a = [
      {'start': 1, 'end': 3},
      {'start': 5, 'end': 6},
      {'start': 8, 'end': 10}
    ]

保证列表是有序的,并且没有任何重叠。给定一个值,我需要找到它在列表中的位置。如果它在定义的范围之一,我需要取回该值。否则,我需要按顺序排列下一个“开始”值。例如,给定b = 2,我会取回值2,因为它在第一个范围内。但是,鉴于 b = 7 的值,我会返回 8,因为它是从 7 开始按顺序排列的下一个范围的起始值。

我为此编写了一些代码:

def where_in_range(v, val_ranges):
  # Check if v comes before all ranges
  if v < val_ranges[0]['start']:
    return val_ranges[0]['start']

  # Check if v is within one of the ranges
  for r in val_ranges:
    if v >= r['start'] and v <= r['end']:
      return v

  # Check if v is between ranges
  for i in range(0, len(val_ranges)-1):
    if v > val_ranges[i]['end'] and v < val_ranges[i+1]['start']:
      return val_ranges[i+1]['start']

  return None

但它似乎非常非pythonic。我愿意使用一个轻量级的包,但是像 pandas 一样重的东西已经出来了,因为它被嵌入到一个 django 应用程序中。有什么想法可以让这更 Pythonic 吗?

【问题讨论】:

  • 使用 numpy 好吗?

标签: python list search range


【解决方案1】:

只需单独检查每个范围。范围内的值会自动处理,任何预范围值也是如此。

def where_in_range(v, val_ranges):
    for d in val_ranges:
        if v < d['start']:
            return d['start']
        elif v < d['end']:
            return v

【讨论】:

  • 噢!我没有只见树木不见森林。这会很好用,但是我确实在 for 循环之后添加了一个 return None 来处理 v 在最终范围之后的情况。谢谢!
  • 如果return语句都没有执行,函数会隐式返回None,但是显式添加它并没有什么坏处。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-05
  • 1970-01-01
  • 2022-06-23
相关资源
最近更新 更多