2011-04-18 15 views
5

Tengo "2,5,7-9,12" cadena.analizar cadena de conjuntos enteros con intervalos para mostrar

Quiero obtener la lista [2, 5, 7, 8, 9, 12] de ella.

¿Hay alguna función incorporada en python?

Gracias.

UPD. Supongo que la respuesta directa es No. De todos modos, gracias por tus "fragmentos". Usando uno, sugerido por Sven Marnach.

+0

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

Respuesta

1

This version maneja espacios en blanco arbitraria, intervalos que se solapan, los intervalos fuera de orden, y números enteros negativos:

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

No que yo sepa, pero se puede hacer fácilmente su propia:

  1. Crear una lista de resultados.
  2. Separe las cadenas por , y comience a repetir el resultado.
    1. Si la cadena actual contiene un -, añada un rango a la lista.
    2. Si la cadena actual es un número, agréguelo a la lista.
    3. Else devuelve un error.
  3. Devuelve la lista.
+0

Alguien debe estar de mal humor para rechazar todas esas respuestas correctas. Los devolveré a cero :) –

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

¿Por qué el voto a favor? Por lo que puedo decir, esto es correcto. –

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)] 

impresiones

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

realmente agradable. Incluso podemos combinarlo en una línea. – disfated

1

No estoy al tanto de cualquier función incorporada que hacer eso. Lo siguiente no es particularmente elegante, pero hace el trabajo:

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 

Un área donde esta solución puede necesitar el trabajo es el manejo de los números negativos (no está del todo claro por su pregunta de si los números negativos pueden aparecer en la entrada).

+2

Esto parece ser correcto también. ¿Por qué downvote? –

+0

En mi caso, solo tengo que manejar int positivos, aunque es bueno tener una solución universal. – disfated

2

Yo definiría función:

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] 
Cuestiones relacionadas