Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python gspread更新_单元非常慢_Python_Python 3.x_Google Sheets_Gspread - Fatal编程技术网

Python gspread更新_单元非常慢

Python gspread更新_单元非常慢,python,python-3.x,google-sheets,gspread,Python,Python 3.x,Google Sheets,Gspread,我有两个谷歌电子表格: QC-许多列,我想检查第四列中的值是否出现在第二个电子表格lastEdited_PEID中;如果是这样的话,它会把“宾果!”在找到该值的同一行的第14列中 lastEdited-一栏,长数值电子表格 我通过以下代码实现了这一点: #acces the documents on Drive QC = gc.open_by_key("FIRST KEY").sheet1 lastEdited = gc.open_by_key("SECOND KEY").sheet1 #ge

我有两个谷歌电子表格:

QC-许多列,我想检查第四列中的值是否出现在第二个电子表格lastEdited_PEID中;如果是这样的话,它会把“宾果!”在找到该值的同一行的第14列中

lastEdited-一栏,长数值电子表格

我通过以下代码实现了这一点:

#acces the documents on Drive
QC = gc.open_by_key("FIRST KEY").sheet1
lastEdited = gc.open_by_key("SECOND KEY").sheet1

#get values from columns and convert to lists 
QC_PEID = QC.col_values(4)
lastEdited_PEID = lastEdited.col_values(1)

#iterate by rows and check if value from each row appears in the second document
for value in QC_PEID:
    ind = QC_PEID.index(value)
    if value in lastEdited_PEID:
        QC.update_cell(ind, 14, 'Bingo!')
所以它完成了这项工作,但速度非常慢(大约5分钟)。我担心速度,因为我必须对大约50个电子表格(每个平均6000行)执行操作

我试图从第二个列表中删除找到的元素(它只能出现一次),循环中有以下代码:

    for value in QC_PEID:
        ind = QC_PEID.index(value)
        if value in lastEdited_PEID:
            QC.update_cell(ind, 14, 'Bingo!')
            **lastEdited_PEID.remove('value')**
我认为这会使它更快,因为参考列表会更短,但令人惊讶的是,它需要更多的时间


我能做些什么来加快这个过程呢?

因为gspread是Google Sheet REST API的包装器,您在电子表格上执行的每个操作都会向API提交HTTP请求。大多数情况下,这是代码中最慢的部分。如果您想提高性能,您需要弄清楚如何减少与API的交互次数

在代码示例中,每个
col\u values()
调用都会发出一个HTTP请求。这很好。但是,当您迭代单元格值时,循环中有一个
update\u cell()

for value in QC_PEID:
    ind = QC_PEID.index(value)
    if value in lastEdited_PEID:
        QC.update_cell(ind, 14, 'Bingo!')  # it makes 2 HTTP requests each time
update\u cell
向API发出两个HTTP请求(一个用于检索更新单元格所需的信息,另一个用于实际向API发送更新)。您需要避免在循环中调用此方法

更好的办法是收集所有更新并成批发送。这就是我们的方法

update\u cells()
需要一个
Cell
对象列表来执行批量更新。您可以通过调用
工作表.range()
来获取这些值

这就是我想到的:

# A utility method
def col_cells(worksheet, col):
    """Returns a range of cells in a `worksheet`'s column `col`."""
    start_cell = self.get_addr_int(1, col)
    end_cell = self.get_addr_int(worksheet.row_count, col)

    return worksheet.range('%s:%s' % (start_cell, end_cell))

QC_PEID = QC.col_values(4)
lastEdited_PEID = set(lastEdited.col_cells(1))  # make the 'in' lookup a bit faster
column_14_cells = col_cells(QC, 14)

has_updates = False
# iterate by rows and check if value from each row appears in the second document
for i, value in enumerate(QC_PEID):
    if value in lastEdited_PEID:
        has_updates = True
        column_14_cells[i].value = 'Bingo!'

if has_updates:
    QC.update_cells(column_14_cells)

我没有运行代码。当心打字错误。

这太神奇了,在我的测试工作表中,过程持续时间从5分钟缩短到。。。2秒!!批量更新会带来不同。万分感谢!