2014-10-12 2 views
0

У меня есть 2 списка:Объединить Python список элементов на основе другого списка

phon = ["A","R","K","H"] 
idx = [1,2,3,3] 

idx соответствует тому, как phon должны быть сгруппированы. В этом случае, phon_grouped должны быть ["A","R","KH"], потому что оба "K" и "H" соответствуют группе 3.

Я предполагаю, что какой-то zip или map функции требуется, но я не уверен, как это осуществить. У меня есть что-то вроде:

a = [] 
for i in enumerate(phon): 
    a[idx[i-1].append(phon[i]) 

, но это на самом деле не работает/компилировать

+0

ли 'idx' отсортированный? Или могут показаться, что индексы вышли из строя? Например. '[3, 2, 1, 3]' для вывода '['K', 'R', 'AH']'? –

+0

Хороший вопрос. Он всегда будет отсортирован. –

+0

Чтобы правильно использовать перечисление, вам нужны две переменные: 'для idx, val in enumerate (a_list)' – IanAuld

ответ

2

Используйте zip() и itertools.groupby() группе выход после проносясь:

from itertools import groupby 
from operator import itemgetter 

result = [''.join([c for i, c in group]) 
      for key, group in groupby(zip(idx, phon), itemgetter(0))] 

itertools.groupby() требует, чтобы ваш вход уже отсортирован на ключ (ваши idx значения здесь).

  • zip() пар индексов вверх от idx с символами из phon
  • itertools.groupby() групп в результате кортежей по первому значению, индекс. Значения равных индексов помещают кортежи в одну и ту же группу
  • Последовательность списка затем выбирает символы из группы и объединяет их в строки.

Демо:

>>> from itertools import groupby 
>>> from operator import itemgetter 
>>> phon = ["A","R","K","H"] 
>>> idx = [1,2,3,3] 
>>> [''.join([c for i, c in group]) for key, group in groupby(zip(idx, phon), itemgetter(0))] 
['A', 'R', 'KH'] 
+0

Спасибо! Питон потрясающий. –

+0

У меня есть небольшая завихренность, если вы за нее: Если какое-либо из значений в 'idx' повторяется 3 или более раз, я хочу исключить это сопоставление, поскольку это, вероятно, ошибка.Это возможно? –

+1

Простейшим решением будет фильтрация после создания подсписного текста, но до объединения строки. Первым шагом будет: 'groups = [(c для i, c в группе) для ключа, group in groupby (zip (idx, phone), itemgetter (0))]' then using filter: 'groups = filter (лямбда g: len (g) <3, groups) ', а затем, наконец, объединив их:' groups = ['' .join (g) для g в группах] ' – justanr

2

Если вы не хотите использовать дополнительный класс:

phon = ["A","R","K","H"] 
idx = [1,2,3,3] 
a = [[] for i in range(idx[-1])] # Create list of lists of length(max(idx)) 
for data,place in enumerate(idx): 
    a[place-1].append(phon[data]) 

[[ 'A'], [ 'R'], [ 'K ',' H ']]

В основном трюк состоит в том, чтобы просто предварительно инициализировать ваш список. Вы знаете, что окончательный список будет иметь максимальное число, найденное в idx, которое должно быть последним числом, как вы сказали, idx сортируется.

Не уверен, что если вы хотите, конечный результат будет литерой список, или сцепленные символы, т.е. «KH» против [ «K», «H»]

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