比较两个大列表并获取匹配的结果

时间:2020-03-25 20:30:58

标签: python python-3.x aws-lambda

我尝试了很多,但是找不到合适的解决方案。我有两个很大的字符串列表,每个列表都有150万条记录。这两个列表都在不同列的where子句中的SQL查询中传递。 例如:Select * from TBL1 where FOO IN (Col1_List) and BAR IN (Col2_list);

由于某些lambda限制,在SQL IN Clause中不支持超过16K的值,因此我希望每次都传递有限的值进行处理,请考虑以下示例:

Col1_list = ['1_a_title','2_title','3_b_title','4_c_title','5_title']  #  and so on ..
Col2_list = ['1_a','2','3_b','4_c','5']  # and so on..

如您所见,Col1_list_title相比,每个值(例如Col2_list)包含一些额外的字符。这两个列表均以整数开头,并且这些整数 可能还会附加其他一些字符(例如 1_a, 3_b )。

目标:我想在IN子句中传递16K值,因此必须将整数部分Col1_listCol2_list匹配以产生正确的sql结果。我尝试了以下代码:

方法1:-循环Col2_list并对其进行匹配以创建匹配记录的新列表:

for i in range(0, len(Col2_list), 16000):
    chunk = Col2_list[i:i + 16000]
    new_kl = []
    for val_to_check in chunk:
      print(val_to_check)
      new_kl.append([item1 for item1 in Col1_list if val_to_check.split('_')[0] == item1.split('_')[0]])
      print(val_to_check + " - " + str(new_kl))
    <Do Processing for obtained 16K values>

方法2:与“理解”尝试相同

for i in range(0, len(Col2_list), 16000):
    chunk = Col2_list[i:i + 16000]
    matched_list = [item for x in chunk for item in Col1_list if item.split('_')[0] == x.split('_')[0]]
    <Do Processing for obtained 16K values>

这两种方法都非常慢。任何人都可以指导我如何更快地做到这一点。

注意:请暂时不要考虑平台,如果需要,我可以在EC2实例上运行脚本,但是仍然需要解决上述问题的方法。

2 个答案:

答案 0 :(得分:0)

根据@AnthonyOteri的建议,我主要在数据库方面进行了处理,并且工作正常且所需时间更少。

答案 1 :(得分:0)

似乎您已经使用数据库解决了这个问题,但是您也可以使用更合适的数据结构在Python中大大加快该过程。

基本上,您正在比较Col2中的每个值和Col1中的每个值,以查看它们是否具有相同的第一个元素。相反,您可以将Col1中的元素按它们的第一个元素进行分组,将它们存储在字典中,然后从该字典中获取与Col2中的值的第一个元素相对应的值。

import collections
col1_dict = collections.defaultdict(list)
for item1 in col1_list:
    col1_dict[item1.split('_')[0]].append(item1)

for i in range(0, len(col2_list), 16000):
    matched_list = [item for val_to_check in col2_list[i:i + 16000]
                         for item in col1_dict[val_to_check.split('_')[0]]]
    # more processing

这会将复杂度从O(#col1 x#col2)降低到O(#col1 +#col2)。 (列表推导仍然有两个for循环,但是由于Col1中的每个项目都恰好在一个“存储桶”中,因此内部循环只有#Col1迭代的 combined 运行时间。 )