Перебор больших списков с потенциальными условиями в Python - PullRequest
1 голос
/ 05 июня 2009

У меня большие порции данных, обычно около 2000+ записей, но в этом отчете у нас есть возможность посмотреть, насколько мы хотим, чтобы это могло быть до 10000 записей

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

Моя проблема заключается в эффективном расчете различных промежуточных итогов. Я использую Django и передаю тег тега валюту и категорию, если это применимо, а затем тег тега отображает итоговое значение. Обратите внимание, что иногда у меня есть промежуточный итог только для категории, без указания валюты.

Первоначально я использовал отдельный запрос для каждой промежуточной суммы, просто используя .filter (), если была валюта / категория, например:

if currency:
  entries = entries.filter(item_currency=currency)

Это стало проблемой, так как у меня было слишком много запросов и слишком много времени генерации (2000+ мс), поэтому я решил использовать список (записи), чтобы выполнить свой запрос сразу, а затем выполнить цикл это с простыми списками:

totals['quantity'] = sum([e.quantity for e in entries])

Моя проблема, если вы ее пока не видите, заключается в том ... как я могу эффективно добавить условие для валюты / категории в каждое понимание списка? Иногда их там не будет, иногда они будут, поэтому я не могу просто напечатать:

totals['quantity'] = sum([e.quantity for e in entries if item_currency = currency])

Я мог бы создать огромный блок if, но он не очень чистый и является катастрофой для техобслуживания, поэтому я обращаюсь к сообществу Stackoverflow за небольшим пониманием .. заранее спасибо:)

1 Ответ

6 голосов
/ 05 июня 2009

Вы можете определить небольшую встроенную функцию:

def EntryMatches(e):
  if use_currency and not (e.currency == currency):
    return False
  if use_category and not (e.category == category):
    return False
  return True

тогда

totals['quantity'] = sum([e.quantity for e in entries if EntryMatches(e)])

EntryMatches () будет иметь доступ ко всем переменным в прилагаемой области видимости, поэтому нет необходимости передавать больше аргументов. Вы получаете преимущество в том, что вся логика, для которой используются записи, находится в одном месте, вы все равно можете использовать понимание списка, чтобы сделать sum () более читабельным, но теперь вы можете иметь произвольную логику в EntryMatches (). *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...