格式化连续数字

时间:2017-03-16 17:55:44

标签: python int format

我正在尝试使用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

感谢您的帮助和见解:)

5 个答案:

答案 0 :(得分:6)

您可以像这样使用groupby模块中的countitertools

编辑:

感谢@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])