Получить индекс элемента в наборе запросов

У меня есть QuerySet, назовем его qs , который упорядочен некоторым атрибутом, который не имеет отношения к этой проблеме. Тогда у меня есть объект, назовем его obj . Теперь я хотел бы узнать, какой индекс obj имеет в qs , насколько это возможно. Я знаю, что я мог бы использовать .index() из Python или, возможно, цикл через qs сравнивающий каждый объект с obj , но каков наилучший способ сделать это? Я ищу высокую производительность, и это мои единственные критерии.

Использование Python 2.6.2 с Django 1.0.2 в Windows.

6 Solutions collect form web for “Получить индекс элемента в наборе запросов”

QuerySets в Django на самом деле являются генераторами, а не списками (для получения дополнительной информации см. Документацию Django на QuerySets ).
Таким образом, нет ярлыка для получения индекса элемента, и я думаю, что простая итерация – лучший способ сделать это.

Для стартера я бы выполнил ваше требование самым простым способом (например, итерацией); если у вас действительно проблемы с производительностью, то я бы использовал несколько разных подходов, например, создание запроса с меньшим количеством полей или что-то еще.
В любом случае, идея состоит в том, чтобы оставить такие трюки как можно дольше, когда вы определенно знаете, что в них нуждаетесь.
Обновление. Возможно, вы захотите напрямую использовать некоторый оператор SQL для получения rownumber (что-то ложь. Однако ORM Django не поддерживает это изначально, и вам нужно использовать необработанный SQL-запрос (см. Документацию ). Я думаю, что это может быть лучший вариант , но опять же – только если вы действительно видите реальную проблему с производительностью.

Компактный и, возможно, самый эффективный:

 for index, item in enumerate(your_queryset): ... 

Если вы просто хотите знать, где вы находитесь, среди всех остальных (например, при определении ранга), вы можете сделать это быстро, посчитав объекты перед вами:

  index = MyModel.objects.filter(sortField__lt = myObject.sortField).count() 

Предполагая с целью иллюстрации, что ваши модели являются стандартными с id первичного ключа, затем оценивая

 list(qs.values_list('id', flat=True)).index(obj.id) 

найдет индекс obj в qs . Хотя использование list оценивает набор запросов, оно оценивает не исходный набор запросов, а производный запрос. Эта оценка запускает SQL-запрос для получения только полей id, не тратя время на извлечение других полей.

Просто для обновления, в первую очередь, набор запросов неупорядочен. Таким образом, индекс может меняться для разных итераций. Вам нужно сделать order_by над любым полем, а затем после ответа Винай поможет в случае, если вам просто нужен индекс.

Вы можете сделать это с помощью queryset.extra(…) и некоторого необработанного SQL:

 queryset = queryset.order_by("id") record500 = queryset[500] numbered_qs = queryset.extra(select={ 'queryset_row_number': 'ROW_NUMBER() OVER (ORDER BY "id")' }) from django.db import connection cursor = connection.cursor() cursor.execute( "WITH OrderedQueryset AS (" + str(numbered_qs.query) + ") " "SELECT queryset_row_number FROM OrderedQueryset WHERE id = %s", [record500.id] ) index = cursor.fetchall()[0][0] index == 501 # because row_number() is 1 indexed not 0 indexed 
  • python pandas dataframe - не может понять, как искать индекс с учетом значения из df
  • Python - лучший язык программирования в мире.