2017-10-06 1 views
0

J'ai une fonction qui prend une chaîne dans un format tel que '1,3-5,7,19' et sortira la liste [1, 3, 4, 5, 7, 19]. Cependant, je pensais que c'était peut-être assez simple à faire avec une compréhension de liste imbriquée.Compréhension de liste imbriquée avec if/else

Ma fonction d'origine est:

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

Je pensais que la compréhension serait quelque chose comme:

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

ou même

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

mais ceux-ci sont SyntaxError. Déplacer le if/else au début de la compréhension comme

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

donne un IndexError: liste index hors de portée.

Est-ce possible? J'ai déjà une fonction qui le gère bien et est plus lisible mais je suis simplement curieux de savoir si cela peut être accompli en python.

+0

Juste pour le fun j'ai décidé de [mettre en œuvre cette Haskell] (https: //gist.github. com/NotTheEconomist/e47de2ee01ae3fcde1926d9df705a079) (en utilisant les paquets 'split' et' text') –

Répondre

2

Vous pouvez définir une petite fonction d'aide:

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

Maintenant, utilisez une compréhension de liste avec une boucle imbriquée.

>>> [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

solution alternative avec re.sub() fonction:

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) 

La sortie:

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