Пересечение списка и первого элемента списка списков
У меня есть два списка:
wordlist = ['A', 'Aani', 'Aaron', 'Aaronic',
'Aaronical', 'Aaronite', 'Aaronitic',
'Aaru', 'Ab', 'Ababdeh']
И
wordlist_compound = [['A','0'], ['Aaronic','1'], ['Key','2'],
['Aaronical','3'], ['Aaronite','4'], ['Yes','5']]
Я хотел бы взять пересечение двух слов и составить список, который содержит слово, комбинацию чисел номер в третьем списке, wordlist_final, так что wordlist_final выглядит следующим образом:
[['A','0'], ['Aaronic','1'], ['Aaronical','3'], ['Aaronite','4']]
Мой текущий код выглядит так:
wordlist_final = []
for index, word in enumerate(wordlist):
for word_comp in wordlist_compound:
if word[index] == wordlist_compound[index][0]:
wordlist_final.append(wordlist_compound[index])
Но я получаю "string index out of range error"
4 ответа:
Ваш вывод легко достигается с помощью понимания списка:
wl=['A', 'Aani', 'Aaron', 'Aaronic', 'Aaronical', 'Aaronite', 'Aaronitic', 'Aaru', 'Ab', 'Ababdeh'] wlc=[['A','0'], ['Aaronic','1'], ['Key','2'], ['Aaronical','3'], ['Aaronite','4'], ['Yes','5']] print [[word, i] for word,i in wlc if word in wl] # [['A', '0'], ['Aaronic', '1'], ['Aaronical', '3'], ['Aaronite', '4']]Альтернативный LC:
print [li for li in wlc if li[0] in wl]Если вам нужна циклическая структура:
wlf = [] for word, i in wlc: if word in wl: wlf.append([word,i]) print wlf # [['A', '0'], ['Aaronic', '1'], ['Aaronical', '3'], ['Aaronite', '4']]Последовательности Pythonобычно не нужно перечислять, чтобы просто иметь дело с объектами в последовательности. Вы обычно должны использовать
enumerateтолько в том случае, если в индексе или порядке есть что-то, что является "данными" в дополнение к самой последовательности.Здесь вы берете каждый элемент в
wordlist_compoundи проверка принадлежности слова вwordlist. Нет необходимости в перечислении. Вы также значительно упростите задачу, если вы перевернете петли; петля надwordlist_compound, а не петля надwordlistво внешнем цикле, как у вас есть. Ваш выход-это фильтр элементов вwordlist_compound; что, конечно, означает, что вы можете использоватьfilterтоже:print filter(lambda li: li[0] in wl, wlc) # [['A', '0'], ['Aaronic', '1'], ['Aaronical', '3'], ['Aaronite', '4']]Ура.
Проблема в том, что
len(wordlist) > len(wordlist_compound), поэтому использованиеindexизwordlistдля индексацииwordlist_compoundдаст индекс из связанных ошибок.Также, как упоминал @ ага, должно быть
if word == wordlist_compound[index][0].
if word[index] == wordlist_compound[index][0]:Я считаю, что это должно быть
if word == wordlist_compound[index][0]:Вы получаете это исключение для элемента
Но это наблюдение не поможет вам, потому что ваш цикл содержит некоторые логические ошибки. Я бы переписал его так:'Aaru': его индекс равен7, а'Aaru'[7]не существует.for inner_list in wordlist_compound: if inner_list[0] in wordlist: wordlist_final.append(inner_list)Или используйте понимание списка, как показал dawg.
В зависимости от размера двух коллекций, я бы, вероятно, сделал это так:
word_numbers = dict(wordlist_compound) wordlist_final = [(word, word_numbers[word]) for word in wordlist if word in word_numbers]Если вы не заботитесь о порядке результата (или если оба списка находятся в одном и том же порядке, в данном случае в алфавитном порядке), то вы можете вместо этого сделать:
words = set(wordlist) wordlist_final = [p for p in wordlist_compound if p[0] in words]Это был бы лучший вариант, если
Я только что заметил, что в обоих случаях я вернул список кортежей, тогда как у вас есть список списков. Вы можете исправить это, если это необходимо. меняяwordlist_compound, вероятно, будет значительно больше, чемwordlist.()на[]в моем первом блоке кода, или меняяp for pнаlist(p) for pво втором.