Пересечение списка и первого элемента списка списков
У меня есть два списка:
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
во втором.