在python中从两个数组进行查找的最快方法

在python中从两个数组进行查找的最快方法,python,python-2.7,Python,Python 2.7,我有三个相同大小的阵列(最长可达5000个)。我必须在前两个数组中查找一对值(这将始终是唯一的),对于ex,(2,3),并相应地从同一索引的第三个数组中获取值。做这件事的最快方法是什么,或者是为此提供的任何简单python内置库是什么?该问题的最简单解决方案是: a = [1,1,1,2,2,2,3,3,3,4,4,4] b = [2,3,4,3,4,5,7,3,2,1,8,9] c = [4,5,6,13,4,8,80,4,2,3,7,11] for i in range(0, len(a))

我有三个相同大小的阵列(最长可达5000个)。我必须在前两个数组中查找一对值(这将始终是唯一的),对于ex,(2,3),并相应地从同一索引的第三个数组中获取值。做这件事的最快方法是什么,或者是为此提供的任何简单python内置库是什么?该问题的最简单解决方案是:

a = [1,1,1,2,2,2,3,3,3,4,4,4]
b = [2,3,4,3,4,5,7,3,2,1,8,9]
c = [4,5,6,13,4,8,80,4,2,3,7,11]
for i in range(0, len(a)):
  if a[i] == 2 and b[i] == 3:
    fetch = c[i]

可以将生成器表达式与所有列表一起使用
next()
zip()

>>> next((z for x, y, z in zip(a, b, c) if (x, y) == (2, 3)), 'None found')
13

可以将生成器表达式与所有列表一起使用
next()
zip()

>>> next((z for x, y, z in zip(a, b, c) if (x, y) == (2, 3)), 'None found')
13

找到索引并使用它:

>>> c[zip(a, b).index((2, 3))]
13
或者准备一份口述来查找这一对:

>>> dict(zip(zip(a, b), c))[2, 3]
13

如果您想查找多对,而不仅仅是一对,这会更快。您可以使用它的
get
,以防该对不存在。

找到索引并使用它:

>>> c[zip(a, b).index((2, 3))]
13
或者准备一份口述来查找这一对:

>>> dict(zip(zip(a, b), c))[2, 3]
13

如果您想查找多对,而不仅仅是一对,这会更快。您可以使用其
get
,以防该对不存在。

使用类似于所示的长度为10000的列表对不同的解决方案进行基准测试,并使用Python 2.7.14搜索所有现有对:

 2.380 seconds rajat      # The original
 1.712 seconds rajat2     #   Precomputed range
 1.843 seconds rajat3     #   xrange instead of range
 5.243 seconds stefan1    # zip(a, b).index
 0.954 seconds stefan1b   #   Precomputed zip(a, b).index
16.108 seconds stefan2    # dict
 0.002 seconds stefan2b   #   Precomputed dict
10.782 seconds chris      # next(generator)
 6.728 seconds chris2     #   bit optimized
 1.754 seconds chris3     #   Precomputed zip(a, b, c)
守则:

from timeit import timeit

b = range(100) * 100
a = sorted(b)
c = range(10000)

#-------------------------------------------------------------------------

def rajat(A, B):
    'The original'
    for i in range(0, len(a)):
        if a[i] == A and b[i] == B:
            return c[i]

def rajat2(A, B, r=range(0, len(a))):
    '  Precomputed range'
    for i in r:
        if a[i] == A and b[i] == B:
            return c[i]

def rajat3(A, B):
    '  xrange instead of range'
    for i in xrange(0, len(a)):
        if a[i] == A and b[i] == B:
            return c[i]

def stefan1(A, B):
    'zip(a, b).index'
    return c[zip(a, b).index((A, B))]

def stefan1b(A, B, index=zip(a, b).index):
    '  Precomputed zip(a, b).index'
    return c[index((A, B))]

def stefan2(A, B):
    'dict'
    return dict(zip(zip(a, b), c))[A, B]

def stefan2b(A, B, d=dict(zip(zip(a, b), c))):
    '  Precomputed dict'
    return d[A, B]

def chris(A, B):
    'next(generator)'
    return next((z for x, y, z in zip(a, b, c) if (x, y) == (A, B)), 'None found')

def chris2(A, B):
    '  bit optimized'
    return next((z for x, y, z in zip(a, b, c) if x == A and y == B), 'None found')

def chris3(A, B, abc=zip(a, b, c)):
    '  Precomputed zip(a, b, c)'
    return next((z for x, y, z in abc if x == A and y == B), 'None found')

#-------------------------------------------------------------------------

ab = zip(a, b)
def test():
    for A, B in ab:
        func(A, B)

for func in rajat, rajat2, rajat3, stefan1, stefan1b, stefan2, stefan2b, chris, chris2, chris3:
    t = timeit(test, number=1)
    print '%6.3f seconds %-10s # %s' % (t, func.__name__, func.__doc__)

对不同的解决方案进行基准测试,使用长度为10000的列表(类似于所示的列表),并使用Python 2.7.14搜索所有现有的对:

 2.380 seconds rajat      # The original
 1.712 seconds rajat2     #   Precomputed range
 1.843 seconds rajat3     #   xrange instead of range
 5.243 seconds stefan1    # zip(a, b).index
 0.954 seconds stefan1b   #   Precomputed zip(a, b).index
16.108 seconds stefan2    # dict
 0.002 seconds stefan2b   #   Precomputed dict
10.782 seconds chris      # next(generator)
 6.728 seconds chris2     #   bit optimized
 1.754 seconds chris3     #   Precomputed zip(a, b, c)
守则:

from timeit import timeit

b = range(100) * 100
a = sorted(b)
c = range(10000)

#-------------------------------------------------------------------------

def rajat(A, B):
    'The original'
    for i in range(0, len(a)):
        if a[i] == A and b[i] == B:
            return c[i]

def rajat2(A, B, r=range(0, len(a))):
    '  Precomputed range'
    for i in r:
        if a[i] == A and b[i] == B:
            return c[i]

def rajat3(A, B):
    '  xrange instead of range'
    for i in xrange(0, len(a)):
        if a[i] == A and b[i] == B:
            return c[i]

def stefan1(A, B):
    'zip(a, b).index'
    return c[zip(a, b).index((A, B))]

def stefan1b(A, B, index=zip(a, b).index):
    '  Precomputed zip(a, b).index'
    return c[index((A, B))]

def stefan2(A, B):
    'dict'
    return dict(zip(zip(a, b), c))[A, B]

def stefan2b(A, B, d=dict(zip(zip(a, b), c))):
    '  Precomputed dict'
    return d[A, B]

def chris(A, B):
    'next(generator)'
    return next((z for x, y, z in zip(a, b, c) if (x, y) == (A, B)), 'None found')

def chris2(A, B):
    '  bit optimized'
    return next((z for x, y, z in zip(a, b, c) if x == A and y == B), 'None found')

def chris3(A, B, abc=zip(a, b, c)):
    '  Precomputed zip(a, b, c)'
    return next((z for x, y, z in abc if x == A and y == B), 'None found')

#-------------------------------------------------------------------------

ab = zip(a, b)
def test():
    for A, B in ab:
        func(A, B)

for func in rajat, rajat2, rajat3, stefan1, stefan1b, stefan2, stefan2b, chris, chris2, chris3:
    t = timeit(test, number=1)
    print '%6.3f seconds %-10s # %s' % (t, func.__name__, func.__doc__)

我不知道这是否更快,但是使用
zip
肯定会带来更多的优雅是
a
按照示例中的排序吗?不,数组没有排序,这只是一个示例我不知道这是否更快,但是使用
zip
肯定会带来更多优雅是
a
按照示例中的排序吗?不,数组没有排序,这只是一个例子很好,我喜欢这个而不是我的approach@Chris_Rands顺便说一句,应该有人做一个适当的基准测试,因为这个问题要求的是最快的方法。在我刚刚做的一个测试中,对于单一搜索,我们所有的解决方案都明显比OP的慢。对于多个搜索,我的搜索速度更快(当我只准备一次dict和index方法时)approach@Chris_Rands顺便说一句,应该有人做一个适当的基准测试,因为这个问题要求的是最快的方法。在我刚刚做的一个测试中,对于单一搜索,我们所有的解决方案都明显比OP的慢。对于多个搜索,我的搜索速度更快(当我只准备一次dict和index方法时)。