Python:通过连接大小将字符串列表拆分为较小块的有效方法

时间:2015-06-22 11:38:31

标签: python string-split google-api-python-client

我通过其google-api-python-client批量请求与Google API进行通信。在批处理请求中存在限制:

  • 批量请求不能包含超过1000个请求
  • 批处理请求在有效负载中的容量不能超过1MB。

我在列表中有随机数字的随机长度字符串,我需要在构建批处理请求的同时记住上述限制。

有没有人知道一种有效的方法来有效地构建可以提交给Google API的原始列表的块?通过有效地'我的意思是,不要遍历第一部分中的所有元素(计算有效载荷大小)。

到目前为止,这就是我的想法:获取最多1000件物品,构建请求,查看有效负载大小。如果它大于1M,请取500,查看大小。如果有效负载较大,请前250个项目。如果有效载荷较小,则需要750件物品。等等,你得到了逻辑。这样,在每次添加后检查它时,可以获得具有少量迭代的元素,而不是构建有效负载。

我真的不想重新发明轮子,所以如果有人知道有效的内置/模块,请告诉我。

当您向实例化的BatchHttpRequest添加了正确数量的请求时,可以通过调用_serialize_request来计算正文有效负载大小。

另请参阅有关批量请求的Python API Client Library documentation

1 个答案:

答案 0 :(得分:0)

好吧,我似乎创造了解决这个问题的东西,这是python中的想法草案:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import random
import string
import sys

MAX_LENGTH = 20
MAX_SIZE = 11111


def get_random():
    return ''.join([
        random.choice(string.ascii_letters) for i in range(
            random.randrange(10, 1000))])


def get_random_list():
    return [get_random() for i in range(random.randrange(50, 1000))]


def get_str_length(rnd_list, item_idx):
    return len(''.join(rnd_list[:item_idx]))

rnd_list = get_random_list()


def calculate_ideal_amount(rnd_list):
    list_bounds = {
        'first': 1,
        'last': len(rnd_list)
    }
    print ('ORIG_SIZE: %s, ORIG_LEN: %s' % (
        get_str_length(rnd_list, len(rnd_list)), len(rnd_list)))
    if get_str_length(rnd_list, list_bounds['first']) > MAX_SIZE:
        return 0
    if get_str_length(rnd_list, list_bounds['last']) <= MAX_SIZE and \
            list_bounds['last'] <= MAX_LENGTH:
        return list_bounds['last']
    while True:
        difference = round((list_bounds['last'] - list_bounds['first']) / 2)
        middle_item_idx = list_bounds['first'] + difference
        str_len = get_str_length(
            rnd_list, middle_item_idx)
        print(
            'MAX_SIZE: %s, list_bounds: %s, '
            'middle_item_idx: %s, diff: %s, str_len: %s,' % (
                MAX_SIZE, list_bounds, middle_item_idx, difference, str_len))
        # sys.stdin.readline()
        if str_len > MAX_SIZE:
            list_bounds['last'] = middle_item_idx
            continue
        if middle_item_idx > MAX_LENGTH:
            return MAX_LENGTH
        list_bounds['first'] = middle_item_idx
        if difference == 0:
            if get_str_length(rnd_list, list_bounds['last']) <= MAX_SIZE:
                if list_bounds['last'] > MAX_LENGTH:
                    return MAX_LENGTH
                return list_bounds['last']
            return list_bounds['first']

ideal_idx = calculate_ideal_amount(rnd_list)

print (
    len(rnd_list), get_str_length(rnd_list, len(rnd_list)),
    get_str_length(rnd_list, ideal_idx), ideal_idx,
    get_str_length(rnd_list, ideal_idx + 1))

这段代码与我试图描述的完全相同,通过在测量其返回(连接)大小的同时查找和修改列表的边界,然后返回列表的索引,它应该被切片以便实现最有效的字符串大小。该方法避免了逐个编译和测量列表的CPU开销。运行此代码将显示它在列表中执行的迭代。

get_str_length,列表和其他功能可以替换为使用API​​客户端中的相应功能,但这是背后的粗略思想。

然而,代码并非万无一失,解决方案应该是这样的。