我正在尝试使用Python格式化整数列表,但是在实现我想要的内容时遇到了一些困难。
输入是整数的排序列表:
list = [1, 2, 3, 6, 8, 9]
我希望输出为String,如下所示:
outputString = "1-3, 6, 8-9"
到目前为止,我设法实现的目标是:
outputString = "1-2-3, 6, 8-9"
如果已经连续,我很难告诉我的代码忽略Int。
到目前为止,这是我的代码:
def format(l):
i = 0
outputString = str(l[i])
for x in range(len(l)-1):
if l[i + 1] == l[i]+1 :
outputString += '-' + str(l[i+1])
else :
outputString += ', ' + str(l[i+1])
i = i + 1
return outputString
感谢您的帮助和见解:)
答案 0 :(得分:6)
您可以像这样使用groupby
模块中的count
和itertools
:
编辑:
感谢@asongtoruin
评论。要从输入中删除重复项,您可以使用:sorted(set(a))
。
from itertools import groupby, count
a = [1, 2, 3, 6, 8, 9]
clustered = [list(v) for _,v in groupby(sorted(a), lambda n, c = count(): n-next(c))]
for k in clustered:
if len(k) > 1:
print("{0}-{1}".format(k[0], k[-1]))
else:
print("{0}".format(k[0]))
输出:
1-3
6
8-9
或许你可以做这样的事情来获得漂亮的输出:
from itertools import groupby, count
a = [1, 2, 3, 6, 8, 9]
clustered = [list(v) for _,v in groupby(sorted(a), lambda n, c = count(): n-next(c))]
out = ", ".join(["{0}-{1}".format(k[0], k[-1]) if len(k) > 1 else "{0}".format(k[0]) for k in clustered ])
print(out)
输出:
1-3, 6, 8-9
答案 1 :(得分:2)
list=[1, 2, 3, 4, 6, 10, 11, 12, 13]
y=str(list[0])
for i in range(0, len(list)-1):
if list[i+1] == list[i]+1 :
y+= '-' + str(list[i + 1])
else:
y+= ',' + str(list[i + 1])
print y
z= y.split(',')
outputString= ''
for i in z:
p=i.split('-')
if p[0] == p[len(p)-1]:
outputString = outputString + str(p[0]) + str(',')
else:
outputString = outputString + str(p[0]) + str('-') + str(p[len(p) - 1]) + str(',')
outputString = outputString[:len(outputString) - 1]
print 'final ans: ',outputString
在代码后添加这些行。
答案 2 :(得分:2)
由于发布此解决方案的其他人删除了他的答案......
这是一个O(n)
字符串构建解决方案:
def stringify(lst):
result = str(lst[0])
end = None
for index, num in enumerate(lst[1:]):
if num - 1 == lst[index]: # the slice shifts the index by 1 for us
end = str(num)
else:
if end:
result += '-' + end
end = None
result += ', ' + str(num)
# Catch the last term
if end:
result += '-' + str(num)
return result
请参阅repl.it
答案 3 :(得分:1)
不是最易读的解决方案,但可以完成工作。可以先确定数据中的跳跃(跳跃=两个元素之间的差异大于1)。然后,您只需遍历原始列表并收集相应的元素并将它们连接到一个字符串。
import numpy as np
l = np.array([1, 2, 3, 6, 8, 9])
# find indexes of jumps in your data
l_diff = np.where(np.diff(l) > 1)[0] + 1
# add one index which makes slicing easier later on
if l_diff[0] != 0:
l_diff = np.insert(l_diff, 0, 0)
# add all the data which are groups of consecutive values
res = []
for ix, i in enumerate(l_diff):
try:
sl = l[i:l_diff[ix + 1]]
if len(sl) > 1:
res.append([sl[0], sl[-1]])
else:
res.append(sl)
# means we reached end of l_diff
except IndexError:
sl = l[i:]
if len(sl) > 1:
res.append([sl[0], sl[-1]])
else:
res.append(sl)
# join the data accordingly, we first have to convert integers to strings
res = ', '.join(['-'.join(map(str, ai)) for ai in res])
然后res
是
'1-3, 6, 8-9'
答案 4 :(得分:1)
这似乎比目前的答案略短,但仍然非常易读。
如果没有使用显式循环构建对象,可能有更好的方法可以做到这一点,但我无法想到一个。
L = [1, 2, 3, 6, 8, 9]
runs = [[str(L[0])]]
for first, second in zip(L, L[1:]):
if second == first + 1:
runs[-1].append(str(second))
else:
runs.append([str(second)])
result = ", ".join(["-".join(run) for run in runs])