2016-06-16 3 views
3

Я получаю список элементов в формате parent.id_child.id, например 1_2. Я попытался сгруппировать идентификатор ребенка с помощью родительского идентификатора, например: с ввода ['1_2', '2_2', '1_1', '2_1', '1_3'] Мне нужен вывод [['1','2','3'], ['1','2']]. Я попытался это:Использование itertools groupby для создания списка списков

inputlist = ['1_2', '1_1', '2_1', '1_3', '2_2' ] 
outputlist= [item.split('_') for item in inputlist] 
outputlist.sort() 
final = [list(group) for key, group in itertools.groupby(outputlist, lambda x: x[0])] 

Это группирует элементы правильно, по мне нужно получить только второй элемент каждого элемента. Как я могу это достичь? Кроме того, могу ли я сделать все это в одном представлении о понимании списка?

ответ

2

Использовать список, да; сами значения передаются в каждую группу итератор без изменений, поэтому вам необходимо снова выбрать:

final = [[g[1] for g in group] for key, group in itertools.groupby(outputlist, lambda x: x[0])] 

Вы можете сделать все это в одном выражении, вкладывая расщепление в groupby вызов, но это становится довольно уродливым быстро, даже если разделить на несколько строк:

final = [ 
    [g[1] for g in group] 
    for key, group in itertools.groupby(
     sorted(item.split('_') for item in inputlist), 
     lambda x: x[0])] 

Вы можете избежать сортировки списка весь входной и только сортировать мелкие группы, используя словарь, чтобы сделать группировку. Dependending от размера ваших идентификаторов, вы можете сортировать иды численно, а также (поскольку текст сортировки сделано лексически):

per_parent = {} 
for item in inputlist: 
    parent, child = item.split('_', 1) 
    per_parent.setdefault(parent, []).append(child) 
final = [children for parent, children in sorted(
    per_parent.items(), key=lambda pc: int(pc[0]))] 

В Python 2, использовать iteritems() вместо items(), чтобы избежать строительства промежуточного список.

+0

Отличный ответ! благодаря – Yasel

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