python - 如何做一个反 `range` ,即根据一组数字创建一个紧凑的范围?

标签 python numbers range pcre

Python 有一个 range 方法,它允许这样的事情:

>>> range(1, 6)
[1, 2, 3, 4, 5]

我正在寻找的是相反的东西:获取一个数字列表,然后返回开始和结束。

>>> magic([1, 2, 3, 4, 5])
[1, 5] # note: 5, not 6; this differs from `range()`

对于上面的例子来说这很容易做到,但是是否也可以允许间隙或多个范围,以类似 PCRE 的字符串格式返回范围?像这样:

>>> magic([1, 2, 4, 5])
['1-2', '4-5']
>>> magic([1, 2, 3, 4, 5])
['1-5']

编辑:我正在寻找 Python 解决方案,但我也欢迎其他语言的工作示例。它更多的是找出一个优雅、高效的算法。奖励问题:是否有任何编程语言为此内置了方法?

最佳答案

简化代码的一个好技巧是查看排序列表的每个元素及其索引的差异:

a = [4, 2, 1, 5]
a.sort()
print [x - i for i, x in enumerate(a)]

打印

[1, 1, 2, 2]

相同数字的每次运行对应于 a 中连续数字的运行。我们现在可以使用 itertools.groupby() 来提取这些运行。完整代码如下:

from itertools import groupby

def sub(x):
    return x[1] - x[0]

a = [5, 3, 7, 4, 1, 2, 9, 10]
ranges = []
for k, iterable in groupby(enumerate(sorted(a)), sub):
     rng = list(iterable)
     if len(rng) == 1:
         s = str(rng[0][1])
     else:
         s = "%s-%s" % (rng[0][1], rng[-1][1])
     ranges.append(s)
print ranges

打印

['1-5', '7', '9-10']

关于python - 如何做一个反 `range` ,即根据一组数字创建一个紧凑的范围?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9470611/

相关文章:

python - Pandas :难以理解合并的工作原理

python - 使用 python 中的 selenium 抓取 youtube 上的所有评论及其回复

python - 如何发出错误而不是系统错误

for-loop - 在范围循环中调用结构体方法

mysql - 按间隔对列 2 排序并对列 1 降序排序

python - 有时无法正确终止 pathos.multiprocessing.Pool

python - 在 django 中创建正则表达式

javascript - JQuery 脚本不能运行两次

c - 找出其中位数最大的数字

algorithm - 如何将整数数组显示为一组范围? (算法)