2016-06-28 4 views
0

У меня есть длинный (много миллионов) список транзакций в форме [account_id, transactiontyp, data], у каждой учетной записи много Сделок. Я хочу выбрать все транзакции для данного короткого списка (около 20000) учетных записей. Пример:python select sublist эффективно

longlist=[['a','t1',5],['a','t1',9],['b','t1',3],['c','t5',8]] 

shortlist=['a','c'] 

Следующий код делает трюк, но экстремально медленно:

selection=[sel for sel in longlist if sel[0] in shortlist] 

Там должны быть более быстрые способы для достижения этой цели? Я попробовал

def select_sample(longlist,shortlist): 
    ret=[] 
    for elem in longlist: 
     if elem[0] in shortlist: 
      ret.append(elem) 
    return ret 

посмотреть, как он масштабируется, как и ожидалось, он линейный по размеру длинного списка. Longlist сортируется по account_id. У меня нет уникального ключа в длинном списке, чтобы использовать словари. Есть ли что-то вроде индексной техники, которую я мог бы использовать?

+0

Вы можете использовать двоичный поиск для отдельных учетных записей [см. Документацию] (https://docs.python.org/2/library/bisect.html#searching-sorted-lists), но затем вам необходимо выполнить это для каждой учетной записи , Я думаю, что должно существовать нечто лучшее. – syntonym

+0

вы можете попробовать с генераторами –

+2

Не совсем полное решение, но подумайте об использовании 'set' вместо списка для проверки:' shortset = set (shortlist) 'и' sel [0] в shortset'. –

ответ

3

Использование set (shortlist = set(['a', 'c']) будет иметь безубыточность около счетов. Я ожидаю, что это будет как минимум на 2 десятилетия быстрее, если shortlist имеет учетные записи 20 тыс.

Если этот выбор повторяется много раз, вы можете использовать еще, используя словарь, который сопоставляет имя учетной записи и список транзакций для этой конкретной учетной записи.


Однако все это пахнет проблемой XY. Неужели вы должны использовать СУБД для управления этими данными? У них есть эффективные алгоритмы для обработки именно таких запросов.

+0

Спасибо, что решает проблему на данный момент. Я был бы признателен за подсказку/ссылку, чтобы понять: почему это имеет такое значение? Является ли python итерацией по списку для каждого наблюдения? – Rriskit

+1

Да. См. [Временная сложность] (https://wiki.python.org/moin/TimeComplexity), время, затрачиваемое на 'x in s', растет линейно для списка и является постоянным для множества по мере их роста. –

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