Pregunta

Tengo una hoja de cálculo cuyos valores quiero rellenar con valores de los diccionarios dentro de una lista. Escribí un bucle para que actualice la celda por celda, pero es demasiado lento y obtengo el gspread.httpsession.httperror a menudo. Estoy tratando de escribir un bucle para actualizar la fila por fila. Eso es lo que tengo:

lstdic=[
{'Amount': 583.33, 'Notes': '', 'Name': 'Jone', 'isTrue': False,},
{'Amount': 58.4, 'Notes': '', 'Name': 'Kit', 'isTrue': False,},
{'Amount': 1083.27, 'Notes': 'Nothing', 'Name': 'Jordan', 'isTrue': True,}
]

Aquí está mi celular por bucle de celda:

headers = wks.row_values(1)

    for k in range(len(lstdic)):
        for key in headers:
            cell = wks.find(key)
            cell_value = lstdic[k][key]
            wks.update_cell(cell.row + 1 + k, cell.col, cell_value)

Qué hace es que encuentra un encabezado que corresponde a la clave en la lista de los diccionarios y actualiza la celda debajo de ella. La siguiente iteración, la fila se incrementa en una, por lo que actualiza las celdas en las mismas columnas, pero la siguiente fila. Esto es demasiado lento y quiero actualizar por fila. Mi intento:

headers = wks.row_values(1)

row=2
for k in range(len(lsdic)):
    cell_list=wks.range('B%s:AA%s' % (row,row))
    for key in headers: 
        for cell in cell_list:
            cell.value = lsdic[k][key]
    row+=1
    wks.update_cells(cell_list)

Este actualiza cada fila rápidamente, pero con el mismo valor. Por lo tanto, el tercer anidado para el bucle asigna el mismo valor para cada celda. Estoy rompiendo mi cabeza tratando de averiguar cómo asignar valores correctos a las celdas. Ayuda apreciada.

P.s. Por cierto, estoy usando encabezados porque quiero un cierto orden en el que aparezca los valores de la hoja de cálculo de Google.

¿Fue útil?

Solución

El siguiente código es similar a la respuesta de Koba, pero escribe la hoja completa a la vez en lugar de por fila.Esto es aún más rápido:

# sheet_data  is a list of lists representing a matrix of data, headers being the first row.
#first make sure the worksheet is the right size
worksheet.resize(len(sheet_data), len(sheet_data[0]))
cell_matrix = []
rownumber = 1

for row in sheet_data:
    # max 24 table width, otherwise a two character selection should be used, I didn't need this.
    cellrange = 'A{row}:{letter}{row}'.format(row=rownumber, letter=chr(len(row) + ord('a') - 1))
    # get the row from the worksheet
    cell_list = worksheet.range(cellrange)
    columnnumber = 0
    for cell in row:
        cell_list[columnnumber].value = row[columnnumber]
        columnnumber += 1
    # add the cell_list, which represents all cells in a row to the full matrix
    cell_matrix = cell_matrix + cell_list
    rownumber += 1
# output the full matrix all at once to the worksheet.
worksheet.update_cells(cell_matrix)

Otros consejos

Terminé escribiendo el siguiente bucle que llena una hoja de cálculo por fila increíblemente rápido.

headers = wks.row_values(1)        
row = 2 # start from the second row because the first row are headers
for k in range(len(lstdic)):
        values=[]
        cell_list=wks.range('B%s:AB%s' % (row,row)) # make sure your row range equals the length of the values list
        for key in headers:
            values.append(lstdic[k][key])   
        for i in range(len(cell_list)):
            cell_list[i].value = values[i]
        wks.update_cells(cell_list)
        print "Updating row " + str(k+2) + '/' + str(len(lstdic) + 1)
        row += 1

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top