Как заполнить список в python на основе другого списка, содержащего некоторые значения из третьего списка?

питон люди. Я искал много форумов для моего вопроса без достаточно хорошего ответа. У меня следующая ситуация: представьте, что у меня есть list1 с идентификаторами пользователей и list2 с их именами. У меня также есть list3 с некоторыми идентификаторами пользователей (из list1), и я хочу создать list4 с именами из list2< /сильный>. Я знаю, что могу легко найти их имена с помощью цикла for, ищущего идентификатор по идентификатору в списке3 и ищу имя пользователя в списке2, но мне нужна скорость, потому что я работаю с миллионами строк. Вот мой фрагмент кода:

for userID in list3:
    index = [i for i, x in enumerate(list1) if x == userID]
    list4.append(list2[index])

Итак, мой вопрос: есть ли более быстрый подход к этой проблеме?

Благодарю вас!


person KAM    schedule 13.07.2020    source источник


Ответы (2)


Допустим, list1, ..., list4 имеют длину n1, ..., n4. Линейное сканирование идентификаторов в списке 3 имеет сложность O (n1 * n3).

Альтернативный подход заключается в создании словаря поиска из list1 и list2. В этом случае сложностью будет создание словаря + поиск, т.е. O(n1) + O(n3).

id2name = dict(zip(list1, list2))    
list4 = [id2name[id] for id in list3]

В большинстве случаев (за исключением очень короткого списка3, 0- или 1-длины) это будет быстрее, чем линейное сканирование.

person Marat    schedule 13.07.2020
comment
Марат, большое спасибо. Ваше предложение значительно сократило время. Теперь логика делается за пару секунд. - person KAM; 13.07.2020

Вы можете использовать index() функцию списка.

for userID in list3:
    list4.append(list2[list1.index(userID))

Я надеюсь, что это сделает ваш код быстрее

person Rajat Agarwal    schedule 13.07.2020
comment
он по-прежнему выполняет линейное сканирование. Лучше всего использовать только на коротких итерациях - person Marat; 13.07.2020
comment
Да, мой первый подход был с index(), но, как говорит Марат, все еще медленное линейное сканирование. Все равно спасибо :) - person KAM; 13.07.2020