2016-09-16 2 views
0

У меня есть список в python, который состоит из буквенных и числовых элементов, скажем что-то вроде list = ["a", 1, 2, 3, "b", 4, 5, 6], и я хочу разрезать его на 2 списка, содержащих числа, которые следуют буквенным символам, поэтому list1 = [1, 2, 3] и list2 = [4, 5, 6]. a и b элементы могут быть в обратном порядке, но в целом я хочу хранить числовые элементы, которые следуют за a и b элементами в отдельных списках. Самое простое решение, что я придумал создавал цикл с условием:Итерирование только части списка в Python

#Generating a list for numeric elements following "a": 
    for e in list[list.index("a")+1:]: 
     if not str.isdigit(e): 
     break 
     else: 
     list1.append(e) 

Я хотел бы сделать это так же для list2 и числовых элементов после "b". Но могли ли быть более элегантные решения? Я новичок в Python, но я видел красивые однострочные конструкции, может быть что-то подобное в моем случае? Заранее спасибо.

+0

Вы можете уточнить вопрос немного больше, например, давая полный пример кода? – linusg

+0

Лучше сейчас: D, но я думаю, что название по-прежнему запутывает ... Вы хотите перебирать список и пропускать определенные элементы или что-то еще? – linusg

ответ

4

Что-то вроде этого, может быть?

>>> import itertools 
>>> import numbers 
>>> lst = ["a", 1, 2, 3, "b", 4, 5, 6] 
>>> groups = itertools.groupby(lst, key=lambda x: isinstance(x, numbers.Number)) 
>>> result = [[x for x in group_iter] for is_number, group_iter in groups if is_number] 
>>> result 
[[1, 2, 3], [4, 5, 6]] 

А вот менее «сексуально» версия, которая выводит список пар кортежей (group_key, group_numbers):

>>> import itertools 
>>> import numbers 
>>> lst = ["a", 1, 2, 3, "b", 4, 5, 6] 
>>> groups = itertools.groupby(lst, key=lambda x: isinstance(x, numbers.Number)) 
>>> group_key = None 
>>> result = [] 
>>> for is_number, group_iter in groups: 
...  if not is_number: 
...   for x in group_iter: 
...    group_key = x 
...  else: 
...   result.append((group_key, [x for x in group_iter])) 
>>> result 
[('a', [1, 2, 3]), ('b', [4, 5, 6])] 

Заметьте, что это быстрая и грязная версия, которая ожидает, что входные данные, чтобы быть хорошо формируется.

+0

как это решение, я сам думал об этом, но не мог до него добраться, спасибо за обмен – Netwave

3

Здесь у вас есть функциональный ПОДХОД:

>>> l = ["a", 1, 2, 3, "b", 4, 5, 6] 
>>> dig = [x for (x, y) in enumerate(l) if type(y) is str] + [len(l)] 
>>> dig 
[0, 4, 8] 
>>> slices = zip(map(lambda x:x+1, dig), dig[1:]) 
>>> slices 
[(1, 4), (5, 8)] 
>>> lists = map(lambda (i, e): l[i:e], slices) 
>>> lists 
[[1, 2, 3], [4, 5, 6]] 

Во-первых, мы получаем индекс писем с, уведомление о том, что нам нужно размер списка, чтобы знать ее конец:

[x for (x, y) in enumerate(l) if type(y) is str] + [len(l)] 

Тогда мы получим пару ломтиков, где списки являются:

zip(map(lambda x:x+1, dig), dig[1:]) 

Наконец, мы получаем каждый кусочек от ориги nal list:

map(lambda (i, e): l[i:e], slices) 
0

Вы можете использовать ломтики:

list = ["a", 1, 2, 3, "b", 4, 5, 6] 
lista = list[list.index('a')+1:list.index('b')] 
listb = list[list.index('b')+1:] 
0

Другой подход (Python 3 только):

def chunks(values, idx=0): 
    ''' Yield successive integer values delimited by a character. ''' 

    tmp = [] 
    for idx, val in enumerate(values[1:], idx): 
     if not isinstance(val, int): 
      yield from chunks(values[idx + 1:], idx) 
      break 
     tmp.append(val) 
    yield tmp 


>>> values = ['a', 1, 2, 3, 'b', 4, 5, 6] 
>>> list(chunks(values)) 
[[4, 5, 6], [1, 2, 3]] 
Смежные вопросы