简体   繁体   English

python-2个列表,并从2个列表中找到最大乘积

[英]python - 2 lists, and finding maximum product from 2 lists

I have two lists made of numbers(integers); 我有两个用数字(整数)组成的清单。 both have 2 million unique elements. 两者都有200万个独特元素。

I want to find number a from list 1 and b from list 2, that - 我想从列表1中找到数字a,从列表2中找到数字b-

1)a*b should be maximized.
2)a*b has to be smaller than certain limit.

here's what I came up with: 这是我想出的:

maxpq = 0
nums = sorted(nums, reverse=True)
nums2 = sorted(nums2, reverse=True)
for p in nums:
    n = p*dropwhile(lambda q: p*q>sqr, nums2).next()
    if n>maxpq:
        maxpq=n
print maxpq

any suggestions? 有什么建议么? edit : my method is too slow. 编辑:我的方法太慢了。 It would take more than one day. 这将需要超过一天的时间。

Here's a linear-time solution (after sorting): 这是线性时间解决方案(排序后):

def maximize(a, b, lim):
    a.sort(reverse=True)
    b.sort()
    found = False
    best = 0
    j = 0
    for i in xrange(len(a)):
        while j < len(b) and a[i] * b[j] < lim:
            found = True
            if a[i]*b[j] > best:
                best, n1, n2 = a[i] * b[j], a[i], b[j]
            j += 1
    return found and (best, n1, n2)

Simply put: 简单的说:

  • start from the highest and lowest from each list 从每个列表的最高和最低开始
  • while their product is less than the target, advance the small-item 当他们的产品小于目标时,推进小项目
  • once the product becomes bigger than your goal, advance the big-item until it goes below again 一旦产品变得超出您的目标,就推进大项目,直到再次下降

This way, you're guaranteed to go through each list only once. 这样,您可以确保只浏览一次每个列表。 It'll return False if it couldn't find anything small enough, otherwise it'll return the product and the pair that produced it. 如果找不到足够小的东西,它将返回False ,否则它将返回产品和生产它的对。

Sample output: 样本输出:

a = [2, 5, 4, 3, 6]
b = [8, 1, 5, 4]
maximize(a, b, 2)   # False
maximize(a, b, 3)   # (2, 2, 1)
maximize(a, b, 10)  # (8, 2, 4)
maximize(a, b, 100) # (48, 6, 8)

Thanks for everyone's advices and ideas. 感谢大家的建议和想法。 I finally came up with useful solution. 我终于想出了有用的解决方案。 Mr inspectorG4dget shone a light on this one. 督察先生G4dget对此亮了点。

It uses bisect module from python's standard library. 它使用python标准库中的bisect模块。

edit : bisect module does binary search in order to find insert position of a value in a sorted list. 编辑:bisect模块进行二进制搜索,以查找值在排序列表中的插入位置。 therefore It reduces number of compares, unlike my previous solution. 因此,与我以前的解决方案不同,它减少了比较次数。

http://www.sparknotes.com/cs/searching/binarysearch/section1.rhtml http://www.sparknotes.com/cs/searching/binarysearch/section1.rhtml

import bisect

def bisect_find(num1, num2, limit):
    num1.sort()    
    max_ab = 0

    for a in num2:
        complement = limit / float(a)
        b = num1[bisect.bisect(num1, complement)-1]

        if limit > a*b > max_ab:
            max_ab=b*a

    return max_ab

This might be faster. 这可能会更快。

def doer(L1, L2, ceil):
    max_c = ceil - 1
    L1.sort(reverse=True)
    L2.sort(reverse=True)
    big_a = big_b = big_c = 0

    for a in L1:
        for b in L2:
            c = a * b
            if c == max_c:
                return a, b
            elif max_c > c > big_c:
                big_a = a
                big_b = b
                big_c = c

    return big_a, big_b


print doer([1, 3, 5, 10], [8, 7, 3, 6], 60)

Note that it sorts the lists in-place; 请注意,它将对列表进行原位排序; this is faster, but may or may not be appropriate in your scenario. 这样比较快,但可能不适用于您的情况。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM