Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.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 在属性\u B排序列表中搜索属性\u A_Python_List_Search_Attributes - Fatal编程技术网

Python 在属性\u B排序列表中搜索属性\u A

Python 在属性\u B排序列表中搜索属性\u A,python,list,search,attributes,Python,List,Search,Attributes,在Python中,在根据属性排序的列表中搜索最有效的方法是什么?请参见下文,了解更精确的问题 例如: class Any (object): def __init__(self, attr_a, attr_b): self.attr_a = attr_a self.attr_b = attr_b L = [Any(-3, 4), Any(-2, 1), Any(0, 2), Any(2, 1), Any(5, 6), Any(6, 3), Any(8,

在Python中,在根据属性排序的列表中搜索最有效的方法是什么?请参见下文,了解更精确的问题

例如:

class Any (object):
    def __init__(self, attr_a, attr_b):
        self.attr_a = attr_a
        self.attr_b = attr_b

L = [Any(-3, 4), Any(-2, 1), Any(0, 2), Any(2, 1), Any(5, 6), Any(6, 3), Any(8, 2), Any(10, 1), Any(13, 5), Any(14, 3)]

L
根据属性
attr\u a
进行排序。列表的所有
Any
实例
L
具有不同的
attr\u a
值。搜索
attr\u a
等于
x
的对象的
attr\u b
值的最有效方法是什么?

要使用模块及其
对分左
函数。在您的情况下,您需要在使用它之前提取密钥列表,有关详细说明,请参阅小节。如果这是不可接受的,那么您可以实现您自己版本的二进制搜索,这是一个简单的算法。

您希望使用模块及其
对分左
函数。在您的情况下,您需要在使用它之前提取密钥列表,有关详细说明,请参阅小节。如果这是不可接受的,那么您可以实现自己版本的二进制搜索,这是一个简单的算法。

您可以采用二进制搜索来为您的
属性值找到正确的
任何
对象。提供了一个起点:

def bisect_left(a, x, lo=0, hi=None, key=None):
    if key is None: key = lambda v: v
    if lo < 0:
        raise ValueError('lo must be non-negative')
    if hi is None:
        hi = len(a)
    while lo < hi:
        mid = (lo+hi)//2
        if key(a[mid]) < x: lo = mid+1
        else: hi = mid
    return lo
这将返回匹配的
Any
的索引,或其
attr\u a
值高于
x
的下一个
Any
对象的索引。您可能需要针对这些情况测试和/或调整算法。例如,您可以验证
attr_a
是否确实匹配所需的值:

def find_by_x(L, x, key):
    index = bisect_left(L, x, key=key)
    if key(L[index]) != x:
        raise IndexError('{} not found'.format(x))
    return L[index]
演示:

>>来自操作员导入属性器
>>>L=[任何(-3,4)、任何(-2,1)、任何(0,2)、任何(2,1)、任何(5,6)、任何(6,3)、任何(8,2)、任何(10,1)、任何(13,5)、任何(14,3)]
>>>x=6
>>>左二等分(L,x,key=attrgetter('attr_a'))
5.
>>>L[bisect_left(L,x,key=attrgetter('attr_a'))].attr_b
3.
>>>通过(L,x,key=attrgetter('attr_a'))查找。attr_b
3.
>>>x=12
>>>通过(L,x,key=attrgetter('attr_a'))查找。attr_b
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“”,第4行,按查找
未找到索引器:12

您应该采用二进制搜索,为您的
attr\u a
值找到正确的
任何
对象。提供了一个起点:

def bisect_left(a, x, lo=0, hi=None, key=None):
    if key is None: key = lambda v: v
    if lo < 0:
        raise ValueError('lo must be non-negative')
    if hi is None:
        hi = len(a)
    while lo < hi:
        mid = (lo+hi)//2
        if key(a[mid]) < x: lo = mid+1
        else: hi = mid
    return lo
这将返回匹配的
Any
的索引,或其
attr\u a
值高于
x
的下一个
Any
对象的索引。您可能需要针对这些情况测试和/或调整算法。例如,您可以验证
attr_a
是否确实匹配所需的值:

def find_by_x(L, x, key):
    index = bisect_left(L, x, key=key)
    if key(L[index]) != x:
        raise IndexError('{} not found'.format(x))
    return L[index]
演示:

>>来自操作员导入属性器
>>>L=[任何(-3,4)、任何(-2,1)、任何(0,2)、任何(2,1)、任何(5,6)、任何(6,3)、任何(8,2)、任何(10,1)、任何(13,5)、任何(14,3)]
>>>x=6
>>>左二等分(L,x,key=attrgetter('attr_a'))
5.
>>>L[bisect_left(L,x,key=attrgetter('attr_a'))].attr_b
3.
>>>通过(L,x,key=attrgetter('attr_a'))查找。attr_b
3.
>>>x=12
>>>通过(L,x,key=attrgetter('attr_a'))查找。attr_b
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“”,第4行,按查找
未找到索引器:12

排序列表最有效的搜索方法是对分算法。有关python的实现,请参见(查看投票数最多的一个)。您需要对其进行修改以找到attr_a,然后再获取attr_b。对于排序列表,最有效的搜索方法是对分算法。有关python的实现,请参见(查看投票数最多的一个)。你需要修改它来找到属性a,然后再得到属性b。这是一个非常好的解决方案!谢谢!很好的解决方案。我有点吃惊,因为我可以得到
x
后面的
attr\u a
值的索引(以及
attr\u b
)!理论上这不应该是个问题,但我们永远不知道。。。我怎么能避免呢?如果没有
任何
实例具有等于
x
attr\u a
,我如何获得错误消息?您必须验证该索引处的对象是否具有
attr\u a
的预期值。我添加了一个先验证的示例函数。好的,我可以在之后检查它。非常感谢@martijnpieters给出的这个很棒的答案,这真是一个很棒的解决方案!谢谢!很好的解决方案。我有点吃惊,因为我可以得到
x
后面的
attr\u a
值的索引(以及
attr\u b
)!理论上这不应该是个问题,但我们永远不知道。。。我怎么能避免呢?如果没有
任何
实例具有等于
x
attr\u a
,我如何获得错误消息?您必须验证该索引处的对象是否具有
attr\u a
的预期值。我添加了一个先验证的示例函数。好的,我可以在之后检查它。非常感谢您的回答@MartijnPieters