Я хотел бы иметь возможность конвертировать строку, такую как "1,2,5-7,10" в список python, такой как [1,2,5,6,7,10]. Я огляделся и нашел этот, но мне было интересно, есть ли в Python чистый и простой способ.
Как преобразовать числовые диапазоны строк в список в Python
Ответ 1
>>> def f(x):
... result = []
... for part in x.split(','):
... if '-' in part:
... a, b = part.split('-')
... a, b = int(a), int(b)
... result.extend(range(a, b + 1))
... else:
... a = int(part)
... result.append(a)
... return result
...
>>> f('1,2,5-7,10')
[1, 2, 5, 6, 7, 10]
Ответ 2
Я смог сделать понимание true по этому вопросу:
>>> def f(s):
return sum(((list(range(*[int(j) + k for k,j in enumerate(i.split('-'))]))
if '-' in i else [int(i)]) for i in s.split(',')), [])
>>> f('1,2,5-7,10')
[1, 2, 5, 6, 7, 10]
>>> f('1,3-7,10,11-15')
[1, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15]
другой ответ, претендующий на понимание, был просто циклом for, потому что окончательный список был отброшен.:)
Для python 2 вы даже можете удалить вызов list
!
Ответ 3
Это может быть перебор, но мне просто нравится пираринг:
from pyparsing import *
def return_range(strg, loc, toks):
if len(toks)==1:
return int(toks[0])
else:
return range(int(toks[0]), int(toks[1])+1)
def parsestring(s):
expr = Forward()
term = (Word(nums) + Optional(Literal('-').suppress() + Word(nums))).setParseAction(return_range)
expr << term + Optional(Literal(',').suppress() + expr)
return expr.parseString(s, parseAll=True)
if __name__=='__main__':
print parsestring('1,2,5-7,10')
код >
Ответ 4
Ух, ответы настолько подробные! Вот короткий и элегантный ответ:
def rangeString(commaString):
def hyphenRange(hyphenString):
x = [int(x) for x in hyphenString.split('-')]
return range(x[0], x[-1]+1)
return chain(*[hyphenRange(r) for r in commaString.split(',')])
Демо:
>>> list( f('1,2,5-7,10') )
[1, 2, 5, 6, 7, 10]
Легко модифицируется для обработки отрицательных чисел или возврата списка. Также потребуется from itertools import chain
, но вы можете заменить sum(...,[])
на него, если вы не работаете с объектами range
(или sum(map(list,iters),[])
), и вам не нужно лениться.
Ответ 5
Никакое понимание не бьет меня!
import re
def convert(x):
return sum((i if len(i) == 1 else list(range(i[0], i[1]+1))
for i in ([int(j) for j in i if j] for i in
re.findall('(\d+),?(?:-(\d+))?', x))), [])
Лучшая часть состоит в том, что я использую переменную i
дважды в середине понимания.
>>> convert('1,2,5-7,10')
[1, 2, 5, 6, 7, 10]
Ответ 6
Очень короткий и элегантный (imho):
>>> txt = "1,2,5-7,10"
>>> # construct list of xranges
>>> xranges = [(lambda l: xrange(l[0], l[-1]+1))(map(int, r.split('-'))) for r in txt.split(',')]
>>> # flatten list of xranges
>>> [y for x in xranges for y in x]
[1, 2, 5, 6, 7, 10]