Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 获取查询集中元素的索引_Python_Django_Indexing_Django Queryset - Fatal编程技术网

Python 获取查询集中元素的索引

Python 获取查询集中元素的索引,python,django,indexing,django-queryset,Python,Django,Indexing,Django Queryset,我有一个查询集,我们称之为qs,它是由一些与这个问题无关的属性排序的。然后我有一个对象,我们称它为obj。现在我想知道obj在qs中的索引是什么,尽可能高效。我知道我可以使用Python中的.index(),或者可能通过qs循环,将每个对象与obj进行比较,但是最好的方法是什么?我在寻找高性能,这是我唯一的标准 在Windows上将Python 2.6.2与Django 1.0.2结合使用。Django中的查询集实际上是生成器,而不是列表(有关详细信息,请参阅)。 因此,获取元素的索引没有捷径,

我有一个查询集,我们称之为
qs
,它是由一些与这个问题无关的属性排序的。然后我有一个对象,我们称它为
obj
。现在我想知道
obj
qs
中的索引是什么,尽可能高效。我知道我可以使用Python中的
.index()
,或者可能通过
qs
循环,将每个对象与
obj
进行比较,但是最好的方法是什么?我在寻找高性能,这是我唯一的标准


在Windows上将Python 2.6.2与Django 1.0.2结合使用。

Django中的查询集实际上是生成器,而不是列表(有关详细信息,请参阅)。
因此,获取元素的索引没有捷径,我认为简单的迭代是最好的方法

对于初学者,我将以最简单的方式实现您的需求(如迭代);如果您确实存在性能问题,那么我将使用一些不同的方法,例如使用较少的字段构建查询集,或者其他任何方法。
在任何情况下,我们的想法都是在你明确知道自己需要这些技巧的时候,尽可能晚地放弃这些技巧。

更新:您可能希望直接使用一些SQL语句来获取行数(有些错误。但是,Django的ORM本机不支持此操作,您必须使用原始SQL查询(请参阅)。我认为这可能是最好的选择,但同样-只有当您真正看到一个真正的性能问题时。

如果您已经在迭代queryset,并且只想知道当前所在元素的索引,那么紧凑且可能最有效的解决方案是:

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

但是,如果您有一个queryset和一个通过一些不相关的方式获得的对象,并且希望了解该对象在queryset中的位置(如果它在那里的话),请不要使用它。

为了说明的目的,假设您的模型是带有主键
id
的标准模型,然后进行评估

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

将在
qs
中找到
obj
的索引。虽然使用
list
计算查询集,但它不会计算原始查询集,而是计算派生查询集。此计算仅运行SQL查询以获取id字段,而不会浪费时间获取其他字段。

如果您只想知道对象在所有字段中的位置其他(例如,在确定等级时),您可以通过计算前面的对象来快速完成:

    index = MyModel.objects.filter(sortField__lt = myObject.sortField).count()
您可以使用和一些原始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方法可以查询queryset中元素的索引:

(*qs,).index(instance)

这个答案将把queryset解压到一个列表中,然后使用内置的Python索引函数来确定它的位置。

我明白了。我上次接触SQL已经有一段时间了,但我想可能在普通SQL中也可以,因此可以使用Django的queryset API。是的,这可能是一个选项。我已经将它添加到了可能的so中解析。这可能比仅评估原始查询集更有效,也可能效率更低,这取决于您以后是否要这样做(因为查询集缓存其结果)。此方法存在问题。qs.values\u list('id',flat=True)在每个步骤中返回不同的值。使用相同的查询可以获得不同的索引。在这种情况下,您还希望
sortField
是唯一的,因为否则您将获得
sortField
等于
myObject.sortField
的第一个元素的位置。它是否应该是
.count()-1
?例如,如果查询集中有1个对象,则索引为0。@david。在这种情况下,表达式将给出0作为计数,因为过滤器使用的是“小于”而不是“小于或等于”。@alexche8它在1000个结果集中的10个结果集上表现得足够好(我随后分页)就更新而言,首先,查询集是无序的。因此,索引可能会因不同的迭代而有所不同。您需要对任何字段执行
order\by
,然后如果您只需要索引,则遵循Vinay的答案将有助于解决问题。如果我们有1000万条记录,则数据库很难操作。这是没有效率的,而且存在内存泄漏由于您正在从python代码中循环遍历表中的每个对象,因此这是一个非常棘手的问题。最有效的答案是使用单个DB查询来获取索引,该索引是Richard的索引answer@Amin_mmz这取决于海报想要什么。如果他们在queryset上迭代,就拥有一个对象并想知道它的位置-
enumerate
就是他们所需要的。这是我对这个问题的理解,也是为什么没有循环体的原因。但是,我发现它可以有不同的解释。如果他们有一个queryset和一个他们认为包含在其中的对象-你是对的,迭代queryset是一个糟糕的想法,Richard的答案是正确的。更好的查询可以是使用SQL
ROW\u NUMBER()
window函数的查询。