2017-03-16 12 views
5

私はPythonで整数のリストを書式化しようとしています。連続した数字をフォーマットする

入力は整数のソートされたリストです:

list = [1, 2, 3, 6, 8, 9] 

私は、出力はこのように見ている文字列であることを、それをしたいと思います:

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

。残念ながら私は今コードを見つけることができません。しかし、 "8,9"は "8-9"より人間が読みやすいと判断されたので、最初の最後の表記は3つ以上の連続した整数に対してのみ使用していました。 – VPfB

答えて

5

あなたがこの方法のようにitertoolsモジュールからgroupbycountを使用することができます。

編集:

@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

あなたの出力は間違っていますか? – TemporalWolf

+1

申し訳ありませんが、私は私の答えを更新しています。 –

+0

更新されました、今すぐ見てください:-) –

1

ありません最も読みやすいソリューションですが、仕事は終わりです。最初にデータのジャンプを決定できます(ジャンプ= 2つの要素の差が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' 
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

...ここ

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

+0

この1つはかなり読みやすいです!しかし、出力にはリストの最後のインデックスが2回あります。 – Yoshiki

+0

@ Yoshikiあ​​なたが正しいです、私はバグを修正し、私の答えを更新しました。 – TemporalWolf

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]) 
関連する問題