TypeError: Sequenzelement 0: erwartete Zeichenfolge, int gefunden

186

Ich versuche, Daten aus einem Wörterbuch in eine Datenbank einzufügen. Ich möchte die Werte durchlaufen und sie je nach Datentyp entsprechend formatieren. Hier ist ein Ausschnitt des Codes, den ich verwende:

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

Wenn ich das Algo mit einigen Beispieldaten ausführe (siehe unten), wird folgende Fehlermeldung angezeigt:

TypeError: Sequenzelement 0: erwartete Zeichenfolge, int gefunden

Ein Beispiel für Wertelistendaten, die den obigen Fehler ergeben, ist:

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] 

Was mache ich falsch?

Homunculus Reticulli
quelle
41
Soulution für Sie:values = ",".join(map(str, value_list))
ddzialak

Antworten:

380

string.join Verbindet Elemente innerhalb der Liste der Zeichenfolgen, nicht Ints.

Verwenden Sie stattdessen diesen Generatorausdruck:

values = ','.join(str(v) for v in value_list)
cval
quelle
31
Kann auch verwenden.join(map(str, value_list))
BallpointBen
44

Obwohl die angegebenen Antworten zum Listenverständnis / Generatorausdruck in Ordnung sind, finde ich dies leichter zu lesen und zu verstehen:

values = ','.join(map(str, value_list))
Kirpit
quelle
2
Ich liebe diese Verwendung von Karte und Str. Ich werde dieses Muster in Zukunft verwenden :)
Timothy C. Quinn
17

Ersetzen

values = ",".join(value_list)

mit

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

ODER

values = ','.join(str(value_list)[1:-1])
Priyank Patel
quelle
1
Ein anderer values = ','.join(str(value_list)[1:-1])
Priyank Patel
4
entfernen Sie die [, ]aus dem zweiten Beispiel eine Liste Verständnis nicht erforderlich ist und von ihnen entfernt haben Sie einen Generator, die effizienter ist.
Jamylak
3
Wie unter stackoverflow.com/questions/9060653/… erläutert , ist die Verwendung einer Liste anstelle eines Generators in der str.join()Methode
tatsächlich
12

Die Antworten von cval und Priyank Patel funktionieren hervorragend. Beachten Sie jedoch, dass einige Werte Unicode-Zeichenfolgen sein können und daher streinen UnicodeEncodeErrorFehler auslösen können . Ersetzen Sie in diesem Fall die Funktion strdurch die Funktion unicode.

Angenommen, die Zeichenfolge Libië (niederländisch für Libyen), die in Python als Unicode-Zeichenfolge dargestellt wird u'Libi\xeb':

print str(u'Libi\xeb')

löst folgenden Fehler aus:

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)

Die folgende Zeile gibt jedoch keinen Fehler aus:

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

Also ersetzen:

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

durch

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

sicher sein.

Tomasz Nguyen
quelle
1
Dies ist hier die beste Lösung! values ​​= ','. join ([Unicode (i) für i in value_list]), der funktioniert, wenn Sie eine Mischung aus Ganzzahlen und Zeichenfolgen mit erweiterten ASCII-Zeichen haben.
Mel
Kein Problem mehr in Python3, str('\xeb')=>ë
Brayoni
0

Die String-Interpolation ist eine gute Möglichkeit, einen formatierten String zu übergeben.

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

Port Edison
quelle
0

Sie können den ganzzahligen Datenrahmen zuerst in einen String konvertieren und dann die Operation ausführen, z

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