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

时间:2018-12-14 11:25:56

标签: python arrays list numpy sorting

我有两个列表。列表B就像一个数据库,我需要一个一个地比较列表A的每个元素。可以说

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是一个有序列表,因此对于每个A [i],只要算法在B中找到> = A [i]的数字,它都应将其作为输出返回。所以我的输出应类似于:

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

能否请您提出最简单的解决方案,尽可能避免嵌套循环?

5 个答案:

答案 0 :(得分:4)

如果您可以使用第三方库,则一种解决方案是通过np.searchsorted进行NumPy:

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])

这比标准库中的顺序循环或基于bisect的算法更有效。

答案 1 :(得分:3)

只需export const loginUser = (email,password) => { return function(dispatch) { // const token = 'my secret token', I dont know where to put it axios.post( 'api/login', {email: email, password: password} ).then((response) => dispatch({type: LOGIN_USER, payload:response})) .catch((error) => { console.log("axios error:",error); }); } } 即可(如果我对您的理解正确):

J = imrotate(I',90) %Rotates your image 90 degrees counterclockwise

答案 2 :(得分:3)

由于#ifndef COMPILE_WPRINTF ... # define CHAR_T char ... #else ... # define CHAR_T wchar_t 已排序,因此可以使用Bbisect中的正确值进行二进制搜索:

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] 的复杂度,其中O(alogb)a的长度分别为bA。像您的示例一样,假设B也已排序,则也可以在A中进行此操作:

O(a+b)

但是请注意,如果i, C = 0, [] for a in A: while B[i] < a: i += 1 C.append(B[i]) 包含的数字大于A中的任何数字,则这两种方法(以及迄今为止发布的其他答案)都将失败。

答案 3 :(得分:1)

由于给定的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

然后只使用列表理解

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

输出

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

另一种方法可能是使用bisect_left软件包中的bisect方法。

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

输出

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

答案 4 :(得分:0)

一种递归方式(对原始列表具有破坏性),在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))
#=> []