Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/347.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_Arrays_Intervals_Binary Search - Fatal编程技术网

Python 查找位于两个值之间的数组元素

Python 查找位于两个值之间的数组元素,python,arrays,intervals,binary-search,Python,Arrays,Intervals,Binary Search,那么问题是这样的: 首先,我用Python编写代码。 我有一个排序自然数的数组(Numpy数组,但如果有帮助的话,我可以把它改成一个列表),“givenY”。我想找到并指向第一个和最后一个元素,其中位于两个指定值之间a=Y[I]和b=Y[I+1]。我写了代码,但我相信我用了最糟糕的方式之一,我不确定代码是否暂时有效。因此,如果我能得到评论或建议从头开始写,我会很高兴。重要的是,当在Y[i]和Y[i+1]之间没有givenY元素时,会出现许多异常情况(这是通过分配-1来处理的)。我的代码是: 这

那么问题是这样的:

首先,我用Python编写代码。 我有一个排序自然数的数组(Numpy数组,但如果有帮助的话,我可以把它改成一个列表),“givenY”。我想找到并指向第一个和最后一个元素,其中位于两个指定值之间
a=Y[I]
b=Y[I+1]
。我写了代码,但我相信我用了最糟糕的方式之一,我不确定代码是否暂时有效。因此,如果我能得到评论或建议从头开始写,我会很高兴。重要的是,当在
Y[i]
Y[i+1]
之间没有givenY元素时,会出现许多异常情况(这是通过分配
-1
来处理的)。我的代码是:

这是binSearch的实施:

def binSearch(arr,element):
left=0
right=arr.size;
mid=(left+right)/2
while left<right:
    mid=(left+right)/2
    if(arr[mid]<element):
        left=mid+1;
    elif (arr[mid]>element):
        right=mid;
    else: 
        return True,mid;
return False,left;
def binSearch(arr,元素):
左=0
右=arr.size;
中间=(左+右)/2
左时,先对列表排序,然后进行线性搜索

删除分号,它们不是必需的,也不是必需的…

先对列表排序,然后进行线性搜索


删除分号,它们不需要也不需要…

我不太理解返回的索引。例如,如果
givenY
为空且列表为空,则
start
end
都将为-1。此外,您发布的代码不会处理列表中的重复值

您可以使用
对分
模块代替手工编码的二进制搜索。有关详细信息,请参阅API文档:

  • 下面是一个返回
    开始
    结束
    的实现,以保持以下属性:

  • end start
    等于给定边界之间的元素数
  • list[start:end]
    返回包含给定边界之间所有值的切片
  • end start
    等于找到的元素数
  • 当未找到值时
    start==end
  • 代码:

    注意:如果需要,返回的起始和结束位置应轻松调整为当前值,只需确保一致即可

    编辑

    下面是返回所请求的值的代码,据我从给出的示例中了解。逻辑在
    find_range()
    docstring中描述。保留原始代码,因为在Python中编程时感觉更自然

    import unittest
    
    from bisect import bisect_left, bisect_right
    
    
    def find_range(array, a, b):
        """Find elements that are greater than a and less than b.
        Returns a tuple (start,end) where array[start] is the first
        value and array[end] is the last value.
        If no value is found, returns start=end=-1.
        """
        start = bisect_right(array,a)
        end = bisect_left(array,b)
        if start==end:
            return (-1,-1)
        else:
            return (start, end-1)
    
    
    class TestCase(unittest.TestCase):
        Y = [1, 3, 5, 10, 15]
        givenY = [3, 4, 5, 6, 7, 8, 9, 10, 11]
    
        def test_empty_array(self):
            self.assertEqual( (-1, -1), find_range([], 1, 2) )
    
        def test_all_values_larger(self):
            self.assertEqual( (-1, -1), find_range([4,5,6], 1, 3) )
    
        def test_all_values_larger_or_equal(self):
            self.assertEqual( (-1, -1), find_range(self.givenY, self.Y[0], self.Y[1]) )
    
        def test_both_endpoints_inside_list(self):
            self.assertEqual( (1, 1), find_range(self.givenY, self.Y[1], self.Y[2]))
    
        def test_2(self):
            self.assertEqual( (3, 6), find_range(self.givenY, self.Y[2], self.Y[3]) )
    
        def test_no_values_larger_or_equal_to_upper_limit(self):
            self.assertEqual( (8, 8), find_range(self.givenY, self.Y[3], self.Y[4]) )
    
        def test_sample(self):
            self.assertEqual( (3,3), find_range([1,3,5,7], 5, 8)  )
            self.assertEqual( (3,3), find_range([1,3,5,7], 6, 8)  )
    
    
    if __name__=="__main__":
        unittest.main()
    

    我不太理解返回的索引。例如,如果
    givenY
    为空且列表为空,则
    start
    end
    都将为-1。此外,您发布的代码不会处理列表中的重复值

    您可以使用
    对分
    模块代替手工编码的二进制搜索。有关详细信息,请参阅API文档:

  • 下面是一个返回
    开始
    结束
    的实现,以保持以下属性:

  • end start
    等于给定边界之间的元素数
  • list[start:end]
    返回包含给定边界之间所有值的切片
  • end start
    等于找到的元素数
  • 当未找到值时
    start==end
  • 代码:

    注意:如果需要,返回的起始和结束位置应轻松调整为当前值,只需确保一致即可

    编辑

    下面是返回所请求的值的代码,据我从给出的示例中了解。逻辑在
    find_range()
    docstring中描述。保留原始代码,因为在Python中编程时感觉更自然

    import unittest
    
    from bisect import bisect_left, bisect_right
    
    
    def find_range(array, a, b):
        """Find elements that are greater than a and less than b.
        Returns a tuple (start,end) where array[start] is the first
        value and array[end] is the last value.
        If no value is found, returns start=end=-1.
        """
        start = bisect_right(array,a)
        end = bisect_left(array,b)
        if start==end:
            return (-1,-1)
        else:
            return (start, end-1)
    
    
    class TestCase(unittest.TestCase):
        Y = [1, 3, 5, 10, 15]
        givenY = [3, 4, 5, 6, 7, 8, 9, 10, 11]
    
        def test_empty_array(self):
            self.assertEqual( (-1, -1), find_range([], 1, 2) )
    
        def test_all_values_larger(self):
            self.assertEqual( (-1, -1), find_range([4,5,6], 1, 3) )
    
        def test_all_values_larger_or_equal(self):
            self.assertEqual( (-1, -1), find_range(self.givenY, self.Y[0], self.Y[1]) )
    
        def test_both_endpoints_inside_list(self):
            self.assertEqual( (1, 1), find_range(self.givenY, self.Y[1], self.Y[2]))
    
        def test_2(self):
            self.assertEqual( (3, 6), find_range(self.givenY, self.Y[2], self.Y[3]) )
    
        def test_no_values_larger_or_equal_to_upper_limit(self):
            self.assertEqual( (8, 8), find_range(self.givenY, self.Y[3], self.Y[4]) )
    
        def test_sample(self):
            self.assertEqual( (3,3), find_range([1,3,5,7], 5, 8)  )
            self.assertEqual( (3,3), find_range([1,3,5,7], 6, 8)  )
    
    
    if __name__=="__main__":
        unittest.main()
    

    谢谢提醒,列表已排序。因此,使用二进制搜索似乎比线性搜索更符合逻辑。我更喜欢分号,它让我想起了C和Java,但感谢您的提及!线性搜索不会比二进制搜索慢吗?谢谢提醒,列表已排序。因此,使用二进制搜索似乎比线性搜索更符合逻辑。我更喜欢分号,它让我想起了C和Java,但感谢您的提及!线性搜索不会比二进制搜索慢吗?请提供示例输入和输出。什么是
    givenY
    ,它是一个列表?请提供示例输入和输出。什么是
    givenY
    ,它是一个列表?非常感谢您的时间,但此代码不起作用:对于givenY=[1,3,5,7],它应该返回(3,3),但返回(3,4)这甚至超出了界限。正如我前面提到的,当a和b之间没有给定值供以后使用时,我将start=-1设置为。在这种情况下,Y[I]和Y[I+1]的值是多少?请阅读这篇文章,因为我已经清楚地定义了返回值是什么。特别是,我声明数组[start:end]将返回介于边界之间的值。在这种特殊情况下,4不在边界之外,
    [1,3,5,7][3:4]
    将返回
    [7]
    ,因为上界指向第一个不包含的元素(类似于C++中的迭代器)。如果您可以指定在不同情况下返回的内容,我将修改代码以处理此问题。它们是整数值,但这并不重要,因为我说过您可以用a和b替换它们。非常感谢,但我希望结束指向间隔中的最后一个元素!我已经在我的文章中写了很多输入和输出(在文章末尾)我想要测试的实际绑定值:)我又添加了一个代码块,我希望它与您最初要求的匹配。基于代码、示例输出和您的评论,我不能完全确定输出是什么。请检查我的docstring,看看它是否符合您的需要。非常感谢您的时间,但此代码不起作用:对于givenY=[1,3,5,7],它应该返回(3,3),但它返回(3,4),甚至超过了界限。正如我前面提到的,当没有givenY va时,我将start=-1设置为
    import unittest
    
    from bisect import bisect_left, bisect_right
    
    
    def find_range(array, a, b):
        start = bisect_right(array,a)
        end = bisect_left(array,b)
        return (start, end)
    
    
    class TestCase(unittest.TestCase):
        Y = [1, 3, 5, 10, 15]
        givenY = [3, 4, 5, 6, 7, 8, 9, 10, 11]
    
        def test_empty_array(self):
            self.assertEqual( (0, 0), find_range([], 1, 2) )
    
        def test_all_values_larger(self):
            self.assertEqual( (0, 0), find_range([4,5,6], 1, 3) )
    
        def test_all_values_larger_or_equal(self):
            self.assertEqual( (0, 0), find_range(self.givenY, self.Y[0], self.Y[1]) )
    
        def test_both_endpoints_inside_list(self):
            self.assertEqual( (1, 2), find_range(self.givenY, self.Y[1], self.Y[2]))
            self.assertEqual( [4], self.givenY[1:2])
    
        def test_2(self):
            self.assertEqual( (3, 7), find_range(self.givenY, self.Y[2], self.Y[3]) )
            self.assertEqual( [6, 7, 8, 9], self.givenY[3:7])
    
        def test_no_values_larger_or_equal_to_upper_limit(self):
            self.assertEqual( (8, 9), find_range(self.givenY, self.Y[3], self.Y[4]) )
            self.assertEqual( [11], self.givenY[8:9])
    
    
    if __name__=="__main__":
        unittest.main()
    
    import unittest
    
    from bisect import bisect_left, bisect_right
    
    
    def find_range(array, a, b):
        """Find elements that are greater than a and less than b.
        Returns a tuple (start,end) where array[start] is the first
        value and array[end] is the last value.
        If no value is found, returns start=end=-1.
        """
        start = bisect_right(array,a)
        end = bisect_left(array,b)
        if start==end:
            return (-1,-1)
        else:
            return (start, end-1)
    
    
    class TestCase(unittest.TestCase):
        Y = [1, 3, 5, 10, 15]
        givenY = [3, 4, 5, 6, 7, 8, 9, 10, 11]
    
        def test_empty_array(self):
            self.assertEqual( (-1, -1), find_range([], 1, 2) )
    
        def test_all_values_larger(self):
            self.assertEqual( (-1, -1), find_range([4,5,6], 1, 3) )
    
        def test_all_values_larger_or_equal(self):
            self.assertEqual( (-1, -1), find_range(self.givenY, self.Y[0], self.Y[1]) )
    
        def test_both_endpoints_inside_list(self):
            self.assertEqual( (1, 1), find_range(self.givenY, self.Y[1], self.Y[2]))
    
        def test_2(self):
            self.assertEqual( (3, 6), find_range(self.givenY, self.Y[2], self.Y[3]) )
    
        def test_no_values_larger_or_equal_to_upper_limit(self):
            self.assertEqual( (8, 8), find_range(self.givenY, self.Y[3], self.Y[4]) )
    
        def test_sample(self):
            self.assertEqual( (3,3), find_range([1,3,5,7], 5, 8)  )
            self.assertEqual( (3,3), find_range([1,3,5,7], 6, 8)  )
    
    
    if __name__=="__main__":
        unittest.main()