2017-10-06 3 views
0

Ich habe eine Funktion, die eine Zeichenfolge in einem Format wie "1,3-5,7,19" nimmt und die Liste [1, 3, 4, 5, 7, 19] ausgeben wird.Nested List Comprehension mit if/else

Allerdings dachte ich, dass das vielleicht einfach genug ist, um mit einem geschachtelten Listenverständnis zu tun.

Meine ursprüngliche Funktion ist:

result = [] 
for x in row_range.split(','): 
    if '-' in x: 
     for y in range(int(x.split('-')[0]), int(x.split('-')[1]) + 1)): 
      result.append(y) 
    else: 
     result.append(int(x)) 

Ich dachte, das Verständnis wäre so etwas wie:

result = [y for x in row_range.split(',') if '-' in x else int(x) for y in range(int(x.split('-')[0]), int(x.split('-')[1] + 1)] 

oder sogar

result = [y for x in row_range.split(',') if '-' in x for y in range(int(x.split('-')[0]), int(x.split('-')[1] + 1) else int(x)] 

aber diese sind Syntax. Das Verschieben der if/else auf der Vorderseite des Verstehens als

result = [y if '-' in x else int(x) for x in row_range.split(',') for y in range(int(x.split('-')[0]), int(x.split('-')[1]) + 1)] 

führt zu einem Indexerror: Listenindex außerhalb des zulässigen Bereichs.

Ist das möglich? Ich habe bereits eine Funktion, die es gut behandelt und lesbarer ist, aber ich bin einfach neugierig, ob dies in Python erreicht werden kann.

def foo(x): 
    x, y = map(int, x.split('-')) 
    return (x, y + 1) 

Verwenden Sie nun eine Liste Verständnis mit einer verschachtelten Schleife:

+0

Just for fun ich beschlossen [implementieren diese in Haskell] (https: //gist.github. com/NotTheEconomist/e47de2ee01ae3fcde1926d9df705a079) (mit den Paketen 'split' und' text') –

Antwort

2

Sie könnten eine kleine Hilfsfunktion definieren.

>>> [y for x in row_range.split(',') 
      for y in ([int(x)] if '-' not in x else range(*foo(x)))] 
[1, 3, 4, 5, 7, 19] 
0

Alternative Lösung mit re.sub() Funktion:

import re 

row_range = '1,3-5,7,8,10-14,19' # extended example 
cb = lambda r: repr(list(range(int(r.group(1)), int(r.group(2))+1)))[1:-1] 
result = [int(i) for i in re.sub(r'(\d+)-(\d+)', cb, row_range).split(',')] 

print(result) 

Der Ausgang:

[1, 3, 4, 5, 7, 8, 10, 11, 12, 13, 14, 19] 
Verwandte Themen