2011-04-18 19 views
5

Mam ciąg znaków "2,5,7-9,12".parsować ciąg liczb całkowitych z przedziałami do listy

Chcę uzyskać z niego listę [2, 5, 7, 8, 9, 12].

Czy jest jakaś funkcja wbudowana w Pythona?

Dzięki.

UPD. Przypuszczam, prosta odpowiedź to nr. W każdym razie, dzięki za twoje "snippets". Korzystanie z jednego, zaproponowanego przez Sven Marnach.

+0

duplikat. http://stackoverflow.com/questions/712460/interpreting-number-ranges-in-python –

Odpowiedz

1

This version obsługuje dowolny spacje, nakładających się zakresów, out-of-order zakresach i ujemne liczby całkowite:

from itertools import chain 

def group_to_range(group): 
    group = ''.join(group.split()) 
    sign, g = ('-', group[1:]) if group.startswith('-') else ('', group) 
    r = g.split('-', 1) 
    r[0] = sign + r[0] 
    r = sorted(int(__) for __ in r) 
    return range(r[0], 1 + r[-1]) 

def rangeexpand(txt): 
    ranges = chain.from_iterable(group_to_range(__) for __ in txt.split(',')) 
    return sorted(set(ranges)) 


>>> rangeexpand('-6,-3--1,3-5,7-11,14,15,17-20') 
[-6, -3, -2, -1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20] 
>>> rangeexpand('1-4,6,3-2, 11, 8 - 12,5,14-14') 
[1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 14] 
1

Nie, że jestem świadomy, ale można łatwo tworzyć własne:

  1. Tworzenie listy wyników.
  2. Podział ciągi według , i rozpocząć iterowanie nad wynikiem.
    1. Jeśli bieżący ciąg zawiera , dodaj zakres do listy.
    2. Jeśli bieżący ciąg jest liczbą, dołącz ją do listy.
    3. Inna zwraca błąd.
  3. Zwróć listę.
+0

Ktoś musi być w złym nastroju, aby zgodzić się z wszystkimi poprawnymi odpowiedziami. Sprowadzę je z powrotem do zera :) –

5
s = "2,5,7-9,12" 
result = list() 

for item in s.split(','): 
    if '-' in item: 
     x,y = item.split('-') 
     result.extend(range(int(x), int(y)+1)) 
    else: 
     result.append(int(item)) 

print result 
+1

Dlaczego spadamy? O ile wiem, jest to poprawne. –

13
s = "2,5,7-9,12" 
ranges = (x.split("-") for x in s.split(",")) 
print [i for r in ranges for i in range(int(r[0]), int(r[-1]) + 1)] 

drukuje

[2, 5, 7, 8, 9, 12] 
+0

Naprawdę ładne. Możemy nawet połączyć go w jedną linię. – disfated

1

nie jestem świadomy każdej wbudowanej funkcji, która by tego nie zrobił. Poniższa nie jest szczególnie elegancki, ale dostaje zadanie:

s = "2,5,7-9,12" 
ret = [] 
for tok in s.split(","): 
    val = map(int, tok.split("-")) 
    if len(val) == 1: 
    ret += val 
    else: 
    ret += range(val[0], val[1] + 1) 
print ret 

Jednym z obszarów, gdzie takie rozwiązanie może wymagać pracy jest obchodzenie się z liczb ujemnych (nie jest do końca jasne, z pytaniem czy liczby ujemne może pojawiać się wejście).

+2

To również wydaje się poprawne. Dlaczego upadek? –

+0

W moim przypadku muszę obsługiwać tylko pozytywne int, chociaż dobrze jest mieć uniwersalne rozwiązanie. – disfated

2

chciałbym zdefiniować funkcję:

def make_range(s): 
    out = [] 
    s = s.split(',') 
    for n in s: 
     if '-' in n: 
      n = n.split('-') 
      for i in range(int(n[0]), int(n[1]) + 1): 
       out.append(i) 
     else: 
      out.append(int(n)) 
    return out 

print make_range("2,5,7-9,12") 
#output [2, 5, 7, 8, 9, 12] 
Powiązane problemy