【发布时间】:2012-04-08 12:12:53
【问题描述】:
我想知道是否有一种简单的(或已经创建的)与此相反的方法:Generate List of Numbers from Hyphenated...。这个链接可以用来做:
>> list(hyphen_range('1-9,12,15-20,23'))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 15, 16, 17, 18, 19, 20, 23]:
我想做相反的事情(请注意,包括 10 和 21,因此它与 range 函数兼容,其中 range(1,10)=[1,2,3,4,5,6, 7,8,9]):
>> list_to_ranges([1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 15, 16, 17, 18, 19, 20, 23])
'1-10,12,15-21,23'
最后,我希望输出也包含一个步骤,其中输出的最后一个数字表示步骤:
>> list_to_ranges([1, 3, 5, 7, 8, 9, 10, 11])
'1-13:2,8,10'
基本上,这最终会有点像“逆”范围函数
>> tmp = list_to_ranges([1, 3, 5])
>> print tmp
'1-7:2'
>> range(1, 7, 2)
[1, 3, 5]
我的猜测是没有真正简单/简单的方法可以做到这一点,但我想我会在这里问一下,然后再做一些蛮力,长方法。
编辑
以this post 的回答中的代码为例,我想出了一个简单的方法来完成第一部分。但我认为确定执行步骤的模式会有点困难。
from itertools import groupby
from operator import itemgetter
data = [ 1, 4,5,6, 10, 15,16,17,18, 22, 25,26,27,28]
print data, '\n'
str_list = []
for k, g in groupby(enumerate(data), lambda (i,x):i-x):
ilist = map(itemgetter(1), g)
print ilist
if len(ilist) > 1:
str_list.append('%d-%d' % (ilist[0], ilist[-1]+1))
else:
str_list.append('%d' % ilist[0])
print '\n', ','.join(str_list)
编辑 2
这是我尝试包含步长大小的尝试......它非常接近,但第一个数字会重复。我认为只要稍微调整一下,它就会接近我想要的——或者至少足够好。
import numpy as np
from itertools import groupby
def list_to_ranges(data):
data = sorted(data)
diff_data = np.diff(data).tolist()
ranges = []
i = 0
for k, iterable in groupby(diff_data, None):
rng = list(iterable)
step = rng[0]
if len(rng) == 1:
ranges.append('%d' % data[i])
elif step == 1:
ranges.append('%d-%d' % (data[i], data[i+len(rng)]+step))
else:
ranges.append('%d-%d:%d' % (data[i], data[i+len(rng)]+step, step))
i += len(rng)
return ','.join(ranges)
data = [1, 3, 5, 6, 7, 11, 13, 15, 16, 17, 18, 19, 22, 25, 28]
print data
data_str = list_to_ranges(data)
print data_str
_list = []
for r in data_str.replace('-',':').split(','):
r = [int(a) for a in r.split(':')]
if len(r) == 1:
_list.extend(r)
elif len(r) == 2:
_list.extend(range(r[0], r[1]))
else:
_list.extend(range(r[0], r[1], r[2]))
print _list
print list(set(_list))
【问题讨论】:
-
你说的蛮力法,根本没必要那么长..
-
我同意。您将不得不解析列表以识别模式,特别是如果您还想添加非统一步骤识别。
-
这里有些歧义:
1-13:2,8,10与1-7:2,7-11相同。在我们真正了解算法之前,您必须对您想要的内容给出更精确的定义。 -
@Winston Ewert:同意。这是我想到的……两者都是有效的输出。我真的不在乎会发生哪个结果,只要它们是等价的。
-
好的,但是
1,3,5,7,8,9,10,11也将等同于1,3,5,7-11。你肯定有某种超越等价的要求。
标签: python list range sequence sequences