Python: json.loads 'u' ön ekine sahip öğeleri döndürür


161

Ben bir JSON kodlanmış dize formu Obj-C alıyorum ve aşağıdaki kod gibi (şimdilik) bir kukla dize çözme. Çıktım, her öğeye önek ekleyen 'u' karakteriyle çıkıyor:

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

JSON bu unicode karakteri nasıl ekliyor? Kaldırmanın en iyi yolu nedir?

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

7
Python'un burada bir sorunu var. Her şey sakin değil. Bu dizeleri bir dosyaya yazmayı denediğimde Python'un oluşturduğu dizelerde hata alıyorum. Örneğin, python JSON'dan "53" aldığında u'53'e dönüştürür ve Python'un mükemmel bir dize almasına ve kusmasına neden olan onaltılık karakter u '\ xe1' olarak bir dosyaya yazmaya çalışır: JSON: {"sa_BstDeAv": "53", "sa_BwVUpMx" ... PYTHON: {u'sa_BstDeAv ': u'53', u'sa_BwVUpMx '... YAZMA HATASI: Değer hatası (' ascii 'codec'i kodlayamıyor 5 konumunda u '\ xe1' karakteri: sıradaki sıralanmayan (128))
David Urry

@janehouse burada doğru cevap jdi tarafından cevap gerçekten değiştirmek gerektiğini düşünüyorum.
Dekel

Yanıtlar:


168

U- öneki bir Unicode dizginiz olduğu anlamına gelir. Dizeyi gerçekten kullandığınızda, verilerinizde görünmez. Yazdırılan çıktı tarafından fırlatılmamalıdır.

Örneğin, şunu deneyin:

print mail_accounts[0]["i"]

Bir u görmeyeceksin.


5
Cevabınız en yararlı
olanıydı

1
Çok teşekkür ederim !
Senin

Kopyalayıp yapıştırmanız dışında uverilerinizde büyük miktarda s vardır. Açıkçası, ubir Unicode dizesi olduğunu belirtmek için a yazdırmak, Python ile ilgili en kötü hatalardan biridir. Tamamen saçma. aASCII ise neden her dizeden önce bir baskı yapmıyorsunuz ? Bir itamsayı ise?
Snowcrash

Python 2'de, Unicode dizeleri bayt dizelerinden farklı bir türdür, bu nedenle verilerin repr'i bunu belirtmek için önek içerir. İçeriğin ne olduğu ile ilgili değil, türüyle ilgili. İçeriği bir Python programına geri yapıştırıyorsanız, u öneki iyidir. Değilse, bunun yerine belki de json.dumps () kullanmak istersiniz.
Ned Batchelder

Json sözlüğünü aramak için dizeyi kullanmanız gerekir. ancak nokta operatörünü kullanamazsınız.
Mart'ta Maddocks


54

Aşağıdaki d3baskı, aradığınız baskıdır (damper ve yüklerin birleşimidir) :)

Having:

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

Baskılar:

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"}

3
Ha? json.dumpsdikteyi tekrar (JSON kodlu) dizeye dönüştürür. OP'nin yapmak istediği bu değildi. -1.
Mark Amery

10
Ama eğer json.loads ile birlikte kullanırsanız bu soruya bir cevap (bu d3 baskı yukarıdadır) kodlanmış karakterler olmadan sözlük çıktısı iyi cevap okuyun!
Merkür

8

uÖnek araçlarının bu dizeleri unicode yerine 8 bit dizeleri olduğunu. uÖneki göstermemenin en iyi yolu , dizelerin varsayılan olarak unicode olduğu Python 3'e geçmektir. Bu bir seçenek değilse, stryapıcı yinelemeli sonucu ve dönüştürmek üzerinde öylesine basit, unicode 8-bit döngü dönüştürür unicodeiçin str. Ancak, dizeleri unicode olarak bırakmak muhtemelen en iyisidir.


8

Unicode burada uygun bir tiptir. JSONDecoder belgeleri, dönüşüm tablosunu tanımlar ve json string nesnelerinin Unicode nesnelerine kodunun çözüldüğünü belirtir

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

"kodlama, bu örnek tarafından çözülen tüm str nesnelerini yorumlamak için kullanılan kodlamayı belirler (varsayılan olarak UTF-8)."


7

Bir nesneye eklenen bu 'u' karakterleri, nesnenin "unicode" olarak kodlandığını gösterir.

Bu 'u' karakterlerini nesnenizden kaldırmak istiyorsanız, bunu yapabilirsiniz:

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

Python kabuğundan çıkış yapalım

>>> 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'}]

Ben her acemi basitçe bu komut dosyasını deneyin ve voila ~ ~ u'JSON çıktı ~ ~ dönüştürmek için bir komut dosyası var :) ... biri sadece komut dosyasına stdin ve sonunda json formatı ekleyebilirsiniz, sen gitmeye hazır!
Jordan Gee

4

loggingHata ayıklama ve sorun giderme amacıyla Python kitaplığıyla günlükteki JSON verilerini yakalamaya çalışırken bu sorunla karşılaşmaya devam ettim . Başlarken uMetni kopyalamak istediğiniz ve kod yerde yapıştırın zaman karakterini gerçek bir sıkıntı olduğunu.

Herkesin size söyleyeceği gibi, bunun nedeni bir Unicode temsilidir ve json.loads()ilk etapta bir dizeden veri yüklemek için kullandığınız gerçeğinden kaynaklanabilir .

Günlükte JSON temsilini istiyorsanız, uÖneki hile, json.dumps()oturumu kapatmadan önce kullanmaktır . Örneğin:

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'}

1
Bu gerçekten en iyi cevap olmalı, 'u' kesinlikle birçok bağlamda "sadece sıyrılmayın". Bunun için çok teşekkürler!
Jessica Pennell

1

Bunu dene:

mail_accounts [0] .encode ( "ASCII")


Herhangi bir açıklama yapmadan cevap neredeyse işe yaramaz. Lütfen bunun neden yardımcı olabileceği gibi bazı bilgiler eklemeyi deneyin.
Abhilash Chandran

Şahsen, çok fazla gereksiz bilgi dikkat dağıtıcı olan uzun cevaplar buluyorum. Yukarıdaki cevaplar zaten değerin unicode olduğunu ve ascii'ye dönüştürülmesi gerektiğini açıklıyor, bu yüzden hepsini tekrarlamıyorum. Değeri elde etmek için daha basit bir yol göstermeniz yeterli. Herkes bu cevabı kullanarak sorun varsa sadece sormak ve ben daha fazla açıklamak için mutluyum! Teşekkürler
2nd Sight Lab

Bu aslında, her bir dizginin 'normal' olarak nasıl yeniden kodlanacağını kesin olarak gösteren bir cevaptır (gülünç derecede verimsiz olması gerekir) json.loads, json.dumps döngüsü.
Ed Randall

0

Sadece u'yu tek bir alıntı ile değiştirin ...

print (str.replace(mail_accounts,"u'","'"))
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.