簡體   English   中英

gspread update_cell非常慢

[英]gspread update_cell very slow

我有兩個Google電子表格:

QC-許多列,我想檢查第二個電子表格lastEdited_PEID中是否有第4列中的值; 如果確實如此,它將顯示“賓果!” 在找到該值的同一行的第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_values()調用都發出一個HTTP請求。 很好 但是,當您遍歷單元格值時,循環中就會有一個update_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_cell向API發出兩個 HTTP請求(一個用於檢索更新單元所需的信息,另一個用於將更新實際發送到API。)您需要避免在循環中調用此方法。

一個更好的主意是收集所有更新並批量發送。 這就是update_cells()方法的作用。

update_cells()需要一個Cell對象列表來進行批量更新。 您可以通過調用Worksheet.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)

我沒有運行代碼。 當心錯別字。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM