Kombinieren mehrerer bedingter Ausdrücke in einem Listenverständnis

I utf-8 kodiere Zeichen wie \ u2013 vor dem Einfügen in SQLite.

Wenn ich sie mit einem SELECT herausziehe, sind sie wieder in ihrer unverschlüsselten Form, also muss ich sie neu kodieren, wenn ich etwas mit ihnen machen will. In diesem Fall möchte ich die Zeilen auf eine CSV schreiben. Vor dem Schreiben der Zeilen in CSV möchte ich zuerst einen Hyperlink zu jeder Zeile hinzufügen, deren Wert mit 'http' beginnt. Einige Werte werden ints, Termine etc, so dass ich die folgenden bedingten Ausdruck – Liste Verständnis Combo:

row = ['=HYPERLINK("%s")' % cell if 'http' in str(cell) else cell for cell in row]. 

Die str() Operation führt dann zu dem bekannten:

UnicodeEncodeError: 'ascii' Codec kann das Zeichen 'u' \ u2013 'nicht in Position 15 codieren: Ordinal nicht im Bereich (128) Fehler.

Was ich dann brauche, ist, den .encode('utf-8') wieder zu codieren, aber nur auf die Elemente in den Listen, die Strings zu beginnen sind. Das folgende wird nicht funktionieren (da nicht alle Elemente Strings sind):

 ['=HYPERLINK("%s")' % cell if 'http' in str(cell).encode('utf8') else cell.encode('utf8') for cell in row] 

TLDR: Wie kann ich das Listenverständnis erweitern / ändern, um nur ein Element zu codieren, wenn es sich um einen String handelt?

  • Selen-Webdriver und Unicode
  • Wenn ein Befehlszeilenprogramm unsicher ist von der Kodierung von stdout, welche Codierung sollte es ausgeben?
  • Entfernen Sie Akzentzeichen Zeichenfolge - Python
  • Wie man korrekt analysiert UTF-8 codierte HTML zu Unicode-Strings mit BeautifulSoup?
  • Konfigurieren Sie IDLE, um Unicode zu verwenden
  • Python, UnicodeEncodeError, Umwandlung von Unicode in ascii
  • Wie kann ich nicht-englischen Unicode-String mit HTTP-Header senden?
  • Encoding Unicode im Wörterbuch Schlüssel auf Japanisch
  • One Solution collect form web for “Kombinieren mehrerer bedingter Ausdrücke in einem Listenverständnis”

    Im Allgemeinen funktioniert die Arbeit in Bezug auf Unicode so lange wie möglich und codiert Unicode zu Bytes (dh str s) nur wenn nötig, wie das Schreiben von Ausgabe in eine Netzwerk-Socket oder Datei.

    Mischen Sie nicht str s mit unicode – obwohl dies in Python2 erlaubt ist, verursacht es Python2 implizit konvertieren str in unicode oder umgekehrt, wie nötig mit dem ascii Codec. Wenn die implizite Codierung oder Decodierung fehlschlägt, bekommt man einen UnicodeEncodingError bzw. UnicodedDecodingError, wie zB den, den du siehst.

    Da die cell u'=HYPERLINK("{}")'.format(cell) ist, verwenden Sie u'=HYPERLINK("{}")'.format(cell) oder u'=HYPERLINK("%s")' % cell anstelle von '=HYPERLINK("%s")' % cell . (Beachten Sie, dass Sie vielleicht url-encode cell in Fall cell enthält ein doppeltes Zitat).

     row = [u'=HYPERLINK("{}")'.format(cell) if isinstance(cell, unicode) and cell.startswith(u'http') else cell for cell in row] 

    Später, wenn / wenn du eine row in str s umwandeln musst, kannst du es benutzen

     row = [cell.encode('utf-8') if isinstance(cell, unicode) else str(cell) for cell in row] 

    Alternativ konvertieren Sie alles in row zu str s zuerst:

     row = [cell.encode('utf-8') if isinstance(cell, unicode) else str(cell) for cell in row] 

    Und dann könntest du das benutzen

     row = ['=HYPERLINK("{}")'.format(cell) if cell.startswith('http') else cell for cell in row] 

    Ähnlich, da row cell enthält cell die Unicode sind, führen Sie den Test durch

     if u'http' in cell 

    Mit dem unicode u'http' anstelle der str 'http' oder besser noch,

     if isinstance(cell, unicode) and cell.startswith(u'http') 

    Obwohl kein Fehler auftritt, wenn du hier 'http' u'http' (da der ascii Codec Bytes im 0-127-Bereich decodieren kann), ist es eine gute Praxis, u'http' zu benutzen u'http' sowieso, da es sich an die Regel anpasst, niemals str und unicode mischen, Und unterstützt geistige Klarheit.

    Python ist die beste Programmiersprache der Welt.