TypeError: elemento de secuencia 0: cadena esperada, int encontrado

188

Estoy intentando insertar datos de un diccionario en una base de datos. Quiero iterar sobre los valores y formatearlos en consecuencia, dependiendo del tipo de datos. Aquí hay un fragmento del código que estoy usando:

def _db_inserts(dbinfo):
    try:
        rows = dbinfo['datarows']

        for row in rows:
            field_names = ",".join(["'{0}'".format(x) for x in row.keys()])
            value_list = row.values()

            for pos, value in enumerate(value_list):
                if isinstance(value, str):
                    value_list[pos] = "'{0}'".format(value)
                elif isinstance(value, datetime):
                    value_list[pos] = "'{0}'".format(value.strftime('%Y-%m-%d'))

            values = ",".join(value_list)

            sql = "INSERT INTO table_foobar ({0}) VALUES ({1})".format(field_names, values)

    except Exception as e:
        print 'BARFED with msg:',e

Cuando ejecuto el algoritmo con algunos datos de muestra (ver más abajo), aparece el error:

TypeError: elemento de secuencia 0: cadena esperada, int encontrado

Un ejemplo de datos de value_list que da el error anterior es:

value_list = [377, -99999, -99999, 'f', -99999, -99999, -99999, 1108.0999999999999, 0, 'f', -99999, 0, 'f', -99999, 'f', -99999, 1108.0999999999999, -99999, 'f', -99999, 'f', -99999, 'f', 'f', 0, 1108.0999999999999, -99999, -99999, 'f', 'f', 'f', -99999, 'f', '1984-04-02', -99999, 'f', -99999, 'f', 1108.0999999999999] 

¿Qué estoy haciendo mal?

Homunculus Reticulli
fuente
42
soulution for you:values = ",".join(map(str, value_list))
ddzialak

Respuestas:

384

string.join conecta elementos dentro de la lista de cadenas, no ints.

Utilice esta expresión generadora en su lugar:

values = ','.join(str(v) for v in value_list)
cval
fuente
32
También puede usar.join(map(str, value_list))
BallpointBen
44

Aunque las respuestas de la lista de comprensión / expresión del generador están bien, me parece más fácil de leer y entender:

values = ','.join(map(str, value_list))
Kirpit
fuente
2
Me encanta este uso de mapa y str. Voy a utilizar este patrón en el futuro :)
Timothy C. Quinn
17

Reemplazar

values = ",".join(value_list)

con

values = ','.join([str(i) for i in value_list])

O

values = ','.join(str(value_list)[1:-1])
Priyank Patel
fuente
1
Otro values = ','.join(str(value_list)[1:-1])
Priyank Patel
44
eliminar el [, ]de su segundo ejemplo, no se requiere una comprensión de la lista y al eliminarlos tiene un generador que es más eficiente.
jamylak
3
En realidad, como se explica en stackoverflow.com/questions/9060653/... , utilizando una lista en lugar de generador en el str.join()método es más rápido ...
dtheodor
12

Las respuestas de cval y Priyank Patel funcionan muy bien. Sin embargo, tenga en cuenta que algunos valores pueden ser cadenas unicode y, por lo tanto, pueden provocar strun UnicodeEncodeErrorerror. En ese caso, reemplace la funciónstr por la funciónunicode .

Por ejemplo, suponga la cadena Libië (holandés para Libia), representada en Python como la cadena unicode u'Libi\xeb':

print str(u'Libi\xeb')

arroja el siguiente error:

Traceback (most recent call last):
  File "/Users/tomasz/Python/MA-CIW-Scriptie/RecreateTweets.py", line 21, in <module>
    print str(u'Libi\xeb')
UnicodeEncodeError: 'ascii' codec can't encode character u'\xeb' in position 4: ordinal not in range(128)

La siguiente línea, sin embargo, no arrojará un error:

print unicode(u'Libi\xeb') # prints Libië

Entonces, reemplace:

values = ','.join([str(i) for i in value_list])

por

values = ','.join([unicode(i) for i in value_list])

para estar seguro.

Tomasz Nguyen
fuente
1
¡Esta es la mejor solución aquí! valores = ','. join ([unicode (i) para i en value_list]) que funciona en caso de que tenga una mezcla de enteros y cadenas con caracteres ascii extendidos.
mel
Ya no es un problema en Python3, str('\xeb')=>ë
Brayoni
0

La interpolación de cadenas es una buena manera de pasar una cadena formateada.

values = ', '.join('$%s' % v for v in value_list)

Port Edison
fuente
0

puede convertir el marco de datos entero en cadena primero y luego realizar la operación, por ejemplo

df3['nID']=df3['nID'].astype(str)
grp = df3.groupby('userID')['nID'].aggregate(lambda x: '->'.join(tuple(x)))
Shaina Raza
fuente