2015-05-12 2 views
8

Прежде чем я спросил, я сделал несколько поисковых запросов и не смог найти ответ.Расширение блока чисел в Python

Сценарий, который у меня есть: Список номеров передается скрипту, \ n-ограниченный через файл или разделенный запятой через командную строку arg. Числа могут быть в единственном числе, или в блоках, например, так:

Файл:

1 
2 
3 
7-10 
15 
20-25 

командной строки Arg:

1, 2, 3, 7-10, 15, 20-25 

И в конечном итоге в том же списке []. Я хотел бы расширить 7-10 или 20-25 блоков (очевидно, в самом сценарии эти цифры будут меняться) и добавить их на новый список с окончательный список вида:

['1','2','3','7','8','9','10','15','20','21','22','23','24','25'] 

Я понимаю, что что-то вроде .append (range (7,10)) может помочь мне здесь, но я не могу понять, какие элементы исходного списка [] нуждаются в расширении.

Итак, мой вопрос заключается в следующем: Учитывая список []:

['1','2','3','7-10','15','20-25'], 

, как я могу получить список []:

['1','2','3','7','8','9','10','15','20','21','22','23','24','25'] 
+0

Возможный дубликат [Развернуть диапазон, который выглядит так: «1-3,6,8-10» to \ [1,2,3, 6, 8 , 9,10 \]] (http://stackoverflow.com/questions/18759512/expand-a-range-which-looks-like-1-3-6-8-10-to-1-2-3- 6-8-9-10) –

ответ

10

Так скажем, вы дали список :

L = ['1','2','3','7-10','15','20-25'] 

и вы хотите, чтобы расшириться все диапазоны, содержащиеся в нем:

answer = [] 
for elem in L: 
    if '-' not in elem: 
     answer.append(elem) 
     continue 
    start, end = elem.split('-') 
    answer.extend(map(str, range(int(start), int(end)+1))) 

Конечно, есть удобный один вкладыш для этого:

answer = list(itertools.chain.from_iterable([[e] if '-' not in e else map(str, range(*[int(i) for i in e.split('-')]) + [int(i)]) for e in L])) 

Но эксплуатирует природу негерметичных переменных в python2.7, которые я не думаю, будет работать в Python3. Кроме того, это не совсем читаемая строка кода. Поэтому я бы не использовал его в производстве, если бы я был вам ... если вы действительно не ненавидите своего менеджера.

Ссылки: append()continuesplit()extend()map()range()list()itertools.chain.from_iterable()int()

+0

Я полностью согласен с вашим решением, я собирался сказать то же самое, но что представляет интерес для карты? –

+0

Работает отлично! Благодаря! –

+0

@AlexandreMazel: 'map' возвращает список в python2, поэтому он сохранил мои вложенные списки. – inspectorG4dget

1

Вход:

arg = ['1','2','3','7-10','15','20-25'] 

Выход:

out = [] 
for s in arg: 
    a, b, *_ = map(int, s.split('-') * 2) 
    out.extend(map(str, range(a, b+1))) 

Или (в Python 2):

out = [] 
for s in arg: 
    r = map(int, s.split('-')) 
    out.extend(map(str, range(r[0], r[-1]+1))) 
0

Хорошая старая карта + сократить будет пригодиться:

>>> elements = ['1','2','3','7-10','15','20-25'] 
>>> reduce(lambda original_list, element_list: original_list + map(str, element_list), [[element] if '-' not in element else range(*map(int, element.split('-'))) for element in elements]) 
['1', '2', '3', '7', '8', '9', '15', '20', '21', '22', '23', '24'] 

Ну что будет делать трюк за исключением того, что вы хотите, 20-25 также содержат 25 ...поэтому здесь приходит еще больше супа:

reduce(
    lambda original_list, element_list: original_list + map(str, element_list), 
    [[element] if '-' not in element 
    else range(int(element.split('-')[0]), int(element.split('-')[1]) + 1) 
    for element in elements]) 

Теперь, несмотря на то, что это работает, вам, вероятно, будет лучше с некоторой петлей. Ну, это причина, по которой они удалили сокращение в python 3.

Смежные вопросы