简体   繁体   English

从排序列表中获取大于给定数字的第一个元素

[英]Get first element greater than a given number from a sorted list

I have two lists. 我有两个清单。 List B is like a database to which I need to compare each element of list A, one by one. 列表B就像一个数据库,我需要逐个比较列表A的每个元素。 Lets say 让我们说

B = [0.6, 1.7, 3, 4.5]
A = [0.6, 0.9, 1.2, 1.5, 2, 2.5, 3, 4, 4.5]

B is a sorted list, so for each A[i] whenever the algorithm finds a number which is >= A[i] in B, it should return that as the output. B是一个排序列表,因此对于每个A [i],只要算法在B中找到一个> = A [i]的数字,它就应该将其作为输出返回。 So my output should look something like: 所以我的输出应该类似于:

C = [0.6, 1.7, 1.7, 1.7, 3, 3, 3, 4.5, 4.5]

Could you please suggest me the simplest solution, avoiding nested loops as much as possible? 能否请您建议最简单的解决方案,尽可能避免嵌套循环?

If you can use a 3rd party library, one solution is NumPy via np.searchsorted : 如果你可以使用第三方库,一个解决方案是NumPy通过np.searchsorted

import numpy as np

B = np.array([0.6, 1.7, 3, 4.5])
A = [0.6, 0.9, 1.2, 1.5, 2, 2.5, 3, 4, 4.5]

res = B[np.searchsorted(B, A)]

array([ 0.6,  1.7,  1.7,  1.7,  3. ,  3. ,  3. ,  4.5,  4.5])

This will be more efficient than a sequential loop or an algorithm based on bisect from the standard library. 这将比顺序循环或基于标准库中的bisect的算法更有效。

Just a next would do ( if I understood you correctly ): 只是next会做( 如果我理解正确的话 ):

A = [0.6, 0.9, 1.2, 1.5, 2, 2.5, 3, 4, 4.5]
B = [0.6, 1.7, 3, 4.5]

C = [next(b for b in B if b >= a) for a in A]

print(C)  # -> [0.6, 1.7, 1.7, 1.7, 3, 3, 3, 4.5, 4.5]

Since B is sorted, you can use bisect to binary-search the correct value in B : 由于B已排序,您可以使用bisect二进制搜索B的正确值:

>>> B = [0.6, 1.7, 3, 4.5]
>>> A = [0.6, 0.9, 1.2, 1.5, 2, 2.5, 3, 4, 4.5]
>>> import bisect
>>> [B[bisect.bisect_left(B, a)] for a in A]
[0.6, 1.7, 1.7, 1.7, 3, 3, 3, 4.5, 4.5]

This has complexity O(alogb) , with a and b being then lengths of A and B respectively. 这具有复杂度O(alogb)ab分别是AB长度。 Assuming that A also is sorted, as in your example, you could also do it in O(a+b) : 假设A也被排序,如在您的示例中,您也可以在O(a+b)

i, C = 0, []
for a in A:
    while B[i] < a:
        i += 1
    C.append(B[i])

Note, however, that both approaches (as well as the other answers posted so far) will fail if A contains a number larger than any number in B . 但请注意,如果A包含的数字大于B任何数字,则两种方法(以及到目前为止发布的其他答案)都将失败。

Since your given B list is sorted, you could use: 由于您的给定B列表已排序,您可以使用:

B = [0.6, 1.7, 3, 4.5]
A = [0.6, 0.9, 1.2, 1.5, 2, 2.5, 3, 4, 4.5]

def first_greater_elem(lst, elem):
    for item in lst:
       if item >= elem:
         return item

Then just use a list comprehension . 然后只使用列表理解

C = [first_greater_elem(B,item) for item in A ]

Output 产量

[0.6, 1.7, 1.7, 1.7, 3, 3, 3, 4.5, 4.5]

Another approach could be using bisect_left method from bisect package. 另一种方法可能是使用bisect包中的bisect_left方法。

C = [B[bisect_left(B,item)] for item in A ]

Output 产量

[0.6, 1.7, 1.7, 1.7, 3, 3, 3, 4.5, 4.5]

A recursive way (destructive for original lists), works also if list_a contains number larger than list_b : 如果list_a包含大于list_b的数字递归方式(对原始列表具有破坏性) 也有效

def pick(lst, ref, res=None):
  if res == None: res = []
  if len(lst) == 0: return res
  if ref[0] >= lst[0]:
    res.append(ref[0])
    lst.pop(0)
  elif len(ref) == 1 and ref[0] < lst[0]:
    # res.extend(lst) # if want to append the rest of lst instead of stop the loop
    # or do whathever is best for you
    return res
  else: ref.pop(0)
  pick(lst, ref, res)
  return res


list_b = [0.6, 1.7, 3, 3.9]
list_bb = [0.5]
list_a = [0.6, 0.9, 1.2, 1.5, 2, 2.5, 3, 4, 4.5]

print(pick(list_a, list_b))
#=> [0.6, 1.7, 1.7, 1.7, 3, 3, 3]

print(pick(list_a, list_bb))
#=> []

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在排序列表中查找大于给定数字的最小数字 - Find the smallest number that is greater than a given number in a sorted list 查找其第一个元素是不大于给定数字的最大值的子列表 - find the sublist whose first element is the maximum that is no greater than a given number 在没有内置排序的情况下从给定列表中排序数字列表,如果第一个数字大于第二个数字则复制它们交换它们 - Order a list of numbers from given list without built-in sort, copy if first number is greater than second number swap them C 函数从按递增顺序排序的数组中返回大于给定数字的最小数字的索引 - C function that returns index of smallest number greater than a given number from an array sorted in increased order Python二进制搜索类函数,用于查找排序列表中第一个大于特定值的数字 - Python binary search-like function to find first number in sorted list greater than a specific value 在列表中查找大于给定值的最小元素 - Finding the smallest element greater than a given value in a list 查找列表中值大于常量的第一个元素 - Find first element in list where value is greater than a constant 从整数列表中,获取最接近并小于给定值的数字 - from list of integers, get number closest to and less than a given value 在Python中,如何在排序列表中找到大于阈值的第一个值的索引? - In Python, how do you find the index of the first value greater than a threshold in a sorted list? 获取列表中给定元素的列表号 - Get list number for a given element in list of lists
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM