Python: json.loads gibt Elemente mit dem Präfix 'u' zurück.

161

Ich erhalte eine JSON-codierte Zeichenfolge von Obj-C und decodiere (vorerst) eine Dummy-Zeichenfolge wie den folgenden Code. Meine Ausgabe wird mit dem Zeichen 'u' ausgegeben, das jedem Element vorangestellt ist:

[{u'i': u'imap.gmail.com', u'p': u'aaaa'}, {u'i': u'333imap.com', u'p': u'bbbb'}...

Wie fügt JSON dieses Unicode-Zeichen hinzu? Was ist der beste Weg, um es zu entfernen?

mail_accounts = []
da = {}
try:
    s = '[{"i":"imap.gmail.com","p":"aaaa"},{"i":"imap.aol.com","p":"bbbb"},{"i":"333imap.com","p":"ccccc"},{"i":"444ap.gmail.com","p":"ddddd"},{"i":"555imap.gmail.com","p":"eee"}]'
    jdata = json.loads(s)
    for d in jdata:
        for key, value in d.iteritems():
            if key not in da:
                da[key] = value
            else:
                da = {}
                da[key] = value
        mail_accounts.append(da)
except Exception, err:
    sys.stderr.write('Exception Error: %s' % str(err))

print mail_accounts
janeh
quelle
7
Python hat hier ein Problem. Alles ist nicht kalt. Ich erhalte Fehler in den von Python erstellten Zeichenfolgen, wenn ich versuche, diese Zeichenfolgen in eine Datei zu schreiben. Wenn Python beispielsweise "53" von JSON nimmt, verwandelt es es in u'53 'und versucht, es als Hex-Zeichen u' \ xe1 'in eine Datei zu schreiben, was dazu führt, dass Python einen perfekt guten String nimmt und darauf kotzt: JSON: {"sa_BstDeAv": "53", "sa_BwVUpMx" ... PYTHON: {u'sa_BstDeAv ': u'53', u'sa_BwVUpMx '... FEHLER BEIM SCHREIBEN: Wertfehler (' ascii'-Codec kann nicht codieren Zeichen u '\ xe1' in Position 5: Ordnungszahl nicht in Reichweite (128))
David Urry
@janehouse Die richtige Antwort hier ist die Antwort von JDI. Ich denke wirklich, du solltest sie ändern.
Dekel

Antworten:

167

Das U-Präfix bedeutet nur, dass Sie eine Unicode-Zeichenfolge haben. Wenn Sie die Zeichenfolge wirklich verwenden, wird sie in Ihren Daten nicht angezeigt. Lassen Sie sich nicht von der gedruckten Ausgabe werfen.

Versuchen Sie zum Beispiel Folgendes:

print mail_accounts[0]["i"]

Du wirst kein u sehen.

Ned Batchelder
quelle
5
Ihre Antwort war die nützlichste, die ich bekommen habe, und ich denke, der Fragesteller dieser Frage hätte es wirklich geschätzt: stackoverflow.com/questions/956867/…
jimh
1
Ich danke dir sehr ! Ich war verwirrt für
dich
Außer wenn Sie es kopieren und einfügen, haben Sie eine große Menge an us in Ihren Daten. Ehrlich gesagt ist das Ausdrucken einer uZeichenfolge als Unicode-Zeichenfolge einer der schlimmsten Fehler bei Python. Äußerst lächerlich. Warum nicht avor jeder Zeichenfolge eine drucken, wenn es sich um ASCII handelt? Und iwenn es eine ganze Zahl ist?
Snowcrash
In Python 2 sind Unicode-Zeichenfolgen ein anderer Typ als Byte-Zeichenfolgen, daher enthält die Darstellung der Daten das Präfix, um dies anzuzeigen. Es geht nicht darum, was der Inhalt ist, es geht um den Typ. Das Präfix u ist in Ordnung, wenn Sie den Inhalt wieder in ein Python-Programm einfügen. Wenn nicht, möchten Sie vielleicht stattdessen json.dumps () verwenden.
Ned Batchelder
Sie müssen die Zeichenfolge verwenden, um das Wörterbuch von json zu durchsuchen. Sie können den Punktoperator jedoch nicht verwenden.
Maddocks
151

Alles ist cool, Mann. Das 'u' ist eine gute Sache, es zeigt an, dass die Zeichenfolge vom Typ Unicode in Python 2.x ist.

http://docs.python.org/2/howto/unicode.html#the-unicode-type

Ein Mann
quelle
71
Ich mag den sehr kühlen Ton von diesem. +1 für eine (richtige) Antwort, die mich zum Lächeln brachte.
mgilson
19
Nur, chill ... (┛◉Д◉) ┛ 彡 ┻━┻
Fulvio
31
Das war die entspannendste Antwort, die ich auf StackOverflow gelesen habe.
aanrv
3
☮ ☮ ☮ Frieden ☮ ☮ ​​☮
sr9yar
54

Der d3Druck unten ist derjenige, den Sie suchen (was die Kombination von Dumps und Ladungen ist) :)

Mit:

import json

d = """{"Aa": 1, "BB": "blabla", "cc": "False"}"""

d1 = json.loads(d)              # Produces a dictionary out of the given string
d2 = json.dumps(d)              # Produces a string out of a given dict or string
d3 = json.dumps(json.loads(d))  # 'dumps' gets the dict from 'loads' this time

print "d1:  " + str(d1)
print "d2:  " + d2
print "d3:  " + d3

Drucke:

d1:  {u'Aa': 1, u'cc': u'False', u'BB': u'blabla'}
d2:  "{\"Aa\": 1, \"BB\": \"blabla\", \"cc\": \"False\"}"
d3:  {"Aa": 1, "cc": "False", "BB": "blabla"}
Merkur
quelle
3
Huh? json.dumpskonvertiert das Diktat zurück in eine (JSON-codierte) Zeichenfolge. Das wollte das OP nicht. -1.
Mark Amery
10
Wenn Sie es jedoch zusammen mit json.loads verwenden, wird das Wörterbuch ohne die codierten Zeichen ausgegeben. Dies ist eine Antwort auf die Frage (dies ist d3-Druck oben). Lesen Sie die Antwort gut!
Merkur
8

Das uPräfix bedeutet, dass diese Zeichenfolgen eher Unicode- als 8-Bit-Zeichenfolgen sind. Der beste Weg, um das uPräfix nicht anzuzeigen, besteht darin, zu Python 3 zu wechseln, wo Zeichenfolgen standardmäßig Unicode sind. Wenn dies keine Option ist, strkonvertiert der Konstruktor von Unicode in 8-Bit. Führen Sie daher einfach eine rekursive Schleife über das Ergebnis durch und konvertieren Sie unicodein str. Es ist jedoch wahrscheinlich am besten, die Zeichenfolgen einfach als Unicode zu belassen.

Abe Karplus
quelle
8

Unicode ist hier ein geeigneter Typ. Die JSONDecoder-Dokumente beschreiben die Konvertierungstabelle und geben an, dass JSON-String-Objekte in Unicode-Objekte dekodiert werden

https://docs.python.org/2/library/json.html#encoders-and-decoders

JSON                    Python
==================================
object                  dict
array                   list
string                  unicode
number (int)            int, long
number (real)           float
true                    True
false                   False
null                    None

"Die Codierung bestimmt die Codierung, die zum Interpretieren aller von dieser Instanz dekodierten str-Objekte verwendet wird (standardmäßig UTF-8)."

jdi
quelle
7

Diese an ein Objekt angehängten 'u'-Zeichen bedeuten, dass das Objekt in "Unicode" codiert ist.

Wenn Sie diese 'u'-Zeichen von Ihrem Objekt entfernen möchten, können Sie dies tun:

import json, ast
jdata = ast.literal_eval(json.dumps(jdata)) # Removing uni-code chars

Lassen Sie uns aus der Python-Shell auschecken

>>> import json, ast
>>> jdata = [{u'i': u'imap.gmail.com', u'p': u'aaaa'}, {u'i': u'333imap.com', u'p': u'bbbb'}]
>>> jdata = ast.literal_eval(json.dumps(jdata))
>>> jdata
[{'i': 'imap.gmail.com', 'p': 'aaaa'}, {'i': '333imap.com', 'p': 'bbbb'}]
Nivesh Krishna
quelle
Ich schlage vor, jeder Neuling probiert einfach dieses Skript aus und voila, Sie haben selbst ein Skript, um ~ von ~ u'JSON-Ausgabe zu konvertieren :) ... wenn man dem Skript nur stdin und am Ende das json-Format hinzufügen kann, sind Sie es bereit zu gehen!
Jordan Gee
4

Dieses Problem trat immer wieder auf, wenn ich versuchte, JSON-Daten im Protokoll mit der Python- loggingBibliothek zu Debugging- und Fehlerbehebungszwecken zu erfassen . Das Erhalten des uCharakters ist ein echtes Ärgernis, wenn Sie den Text kopieren und irgendwo in Ihren Code einfügen möchten.

Wie jeder Ihnen sagen wird, liegt dies daran, dass es sich um eine Unicode-Darstellung handelt und dass dies möglicherweise darauf zurückzuführen ist, dass Sie json.loads()die Daten ursprünglich aus einer Zeichenfolge geladen haben.

Wenn Sie die JSON-Darstellung im Protokoll ohne uPräfix verwenden möchten , besteht der Trick darin, sie zu verwendenjson.dumps() vor dem Abmelden verwenden. Beispielsweise:

import json
import logging

# Prepare the data
json_data = json.loads('{"key": "value"}')

# Log normally and get the Unicode indicator
logging.warning('data: {}'.format(json_data))
>>> WARNING:root:data: {u'key': u'value'}

# Dump to a string before logging and get clean output!
logging.warning('data: {}'.format(json.dumps(json_data)))
>>> WARNING:root:data: {'key': 'value'}
Jonatan
quelle
1
Dies sollte wirklich die beste Antwort sein, die 'u' werden in vielen Zusammenhängen absolut nicht "einfach ausgezogen". Vielen Dank dafür!
Jessica Pennell
1

Versuche dies:

mail_accounts [0] .encode ("ascii")

2nd Sight Lab
quelle
Eine Antwort ohne Erklärung ist fast nutzlos. Bitte versuchen Sie einige Informationen hinzuzufügen, z. B. warum dies helfen würde.
Abhilash Chandran
Persönlich finde ich lange Antworten mit zu vielen unnötigen Informationen ablenkend. Die obigen Antworten erklären bereits, dass der Wert Unicode ist und in ASCII konvertiert werden muss, damit ich das alles nicht wiederhole. Nur einen einfacheren Weg zeigen, um den Wert zu erhalten. Wenn jemand Probleme mit dieser Antwort hat, fragen Sie einfach und ich erkläre es Ihnen gerne weiter! Vielen Dank
2nd Sight Lab
Dies ist tatsächlich die einzige Antwort, die genau zeigt, wie jeder String auf "normal" umcodiert werden kann, ohne einen (was lächerlich ineffizient sein muss) json.loads, json.dumps-Zyklus zu durchlaufen.
Ed Randall
0

Ersetzen Sie einfach das u 'durch ein einfaches Anführungszeichen ...

print (str.replace(mail_accounts,"u'","'"))
Mikematik
quelle