Как преобразовать числовые строковые диапазоны в список в Python - PullRequest
18 голосов
/ 20 июня 2011

Я хотел бы иметь возможность преобразовать строку, такую ​​как "1,2,5-7,10", в список Python, например [1,2,5,6,7,10] Я оглянулся и нашел это , но мне было интересно, есть ли простой и простой способ сделать это в Python.

Ответы [ 6 ]

28 голосов
/ 20 июня 2011
>>> 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]
5 голосов
/ 20 июня 2011

Я смог сделать истинное понимание по этому вопросу:

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

2 голосов
/ 20 июня 2011

Это может быть излишним, но я просто люблю pyparsing:

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')
1 голос
/ 30 сентября 2013

Очень короткий и элегантный (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]
1 голос
/ 20 июня 2011

Никакое понимание не сравнится с моим!

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]
1 голос
/ 20 июня 2011

Тьфу, ответы настолько многословны! Вот короткий и элегантный ответ:

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),[])), и вам не важно быть ленивым.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...