Python: json.loads คืนค่ารายการที่ขึ้นต้นด้วย 'u'


161

ฉันจะได้รับรูปแบบสตริงที่เข้ารหัส JSON Obj-C และฉันกำลังถอดรหัสสตริงดัมมี่ (ตอนนี้) เช่นรหัสด้านล่าง ผลลัพธ์ของฉันออกมาพร้อมกับอักขระ 'u' นำหน้าแต่ละรายการ:

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

JSON จะเพิ่มตัวอักษร unicode นี้ได้อย่างไร? วิธีลบที่ดีที่สุดคืออะไร

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 มีปัญหาที่นี่ ทุกอย่างไม่เย็น ฉันได้รับข้อผิดพลาดในสตริงที่ Python สร้างขึ้นเมื่อฉันพยายามเขียนสตริงเหล่านี้ไปยังไฟล์ ตัวอย่างเช่นเมื่อ python ใช้ "53" จาก JSON มันจะเปลี่ยนเป็น u'53 'และพยายามเขียนลงในไฟล์เป็นอักขระฐานสิบหก u' \ xe1 'ซึ่งทำให้ Python ใช้สตริงที่ดีอย่างสมบูรณ์และ puke บนมัน: JSON: {"sa_BstDeAv": "53", "sa_BwVUpMx" ... PYTHON: {u'sa_BstDeAv ': u'53', u'sa_BwVUpMx '... ข้อผิดพลาดของค่า (' ascii 'codec ไม่สามารถเข้ารหัสได้ อักขระ u '\ xe1' ในตำแหน่งที่ 5: ลำดับไม่อยู่ในช่วง (128))
David Urry

@janehouse คำตอบที่ถูกต้องที่นี่คือคำตอบโดย jdi ฉันคิดว่าคุณควรเปลี่ยน
Dekel

คำตอบ:


168

คำนำหน้าเพียงหมายความว่าคุณมีสายอักขระ Unicode เมื่อคุณใช้สตริงจริง ๆ สตริงนั้นจะไม่ปรากฏในข้อมูลของคุณ อย่าถูกโยนโดยเอาท์พุทที่พิมพ์ออกมา

ตัวอย่างเช่นลองสิ่งนี้:

print mail_accounts[0]["i"]

คุณจะไม่เห็นคุณ


5
คำตอบของคุณมีประโยชน์มากที่สุดที่ฉันได้รับและฉันคิดว่าผู้ถามคำถามนี้จะได้รับความชื่นชมจริง ๆ : stackoverflow.com/questions/956867/…
jimh

1
ขอบคุณมาก ! ฉันสับสนสำหรับจดหมายของคุณนานมาก
ketan khandagale

ยกเว้นในกรณีที่คุณคัดลอกและวางคุณมีข้อมูลจำนวนuมาก ตรงไปตรงมาการพิมพ์uเพื่อระบุว่าเป็นสตริง Unicode เป็นหนึ่งในข้อผิดพลาดที่เลวร้ายที่สุดเกี่ยวกับ Python ไร้สาระที่สุด ทำไมไม่พิมพ์aก่อนทุกสตริงถ้าเป็น ASCII iถ้ามันเป็นจำนวนเต็ม?
Snowcrash

ใน Python 2 สตริง Unicode เป็นชนิดที่แตกต่างจากสตริงไบต์ดังนั้นการพิมพ์ข้อมูลจึงมีคำนำหน้าเพื่อระบุว่า มันไม่เกี่ยวกับเนื้อหาที่เกิดขึ้น แต่เกี่ยวกับประเภท คำนำหน้า u นั้นใช้ได้ถ้าคุณวางเนื้อหากลับเข้าไปในโปรแกรม Python ถ้าไม่เช่นนั้นคุณอาจต้องการใช้ json.dumps () แทน
Ned Batchelder

คุณต้องใช้สตริงเพื่อค้นหาพจนานุกรมของ json อย่างไรก็ตามคุณไม่สามารถใช้ตัวดำเนินการ dot ได้
Maddocks

151

ทุกอย่างเจ๋งมาก 'u' เป็นสิ่งที่ดีแสดงว่าสตริงนั้นเป็นชนิด Unicode ใน python 2.x

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


71
ฉันชอบเสียงที่เย็นยะเยือกของอันนี้ +1 สำหรับคำตอบ (ถูกต้อง) ที่ทำให้ฉันยิ้มได้
mgilson

19
แค่ทำใจให้สบาย ... (┛◉Д◉) ┛彡┻━┻
fulvio

31
นั่นเป็นคำตอบที่ผ่อนคลายที่สุดที่ฉันได้อ่านใน StackOverflow
aanrv

3
☮☮☮สันติภาพ☮☮☮
sr9yar

54

d3พิมพ์ด้านล่างเป็นคนที่คุณกำลังมองหา (ซึ่งก็คือการรวมกันของทิ้งและโหลด) :)

มี:

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

พิมพ์:

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
ฮะ? json.dumpsแปลง dict กลับเป็นสตริง (เข้ารหัส JSON) นั่นไม่ใช่สิ่งที่ OP ต้องการทำ -1
Mark Amery

10
แต่ถ้าคุณใช้ร่วมกับ json.loads มันจะออกพจนานุกรมโดยไม่มีตัวอักษรที่เข้ารหัสซึ่งเป็นคำตอบสำหรับคำถาม (นี่คือการพิมพ์ d3 ด้านบน) อ่านคำตอบได้ดี!
พุธ

8

uคำนำหน้าหมายความว่าผู้ที่มีสตริง Unicode มากกว่าสตริง 8 บิต วิธีที่ดีที่สุดที่จะไม่แสดงuคำนำหน้าคือเปลี่ยนเป็น Python 3 โดยที่สตริงเป็นยูนิโค้ดตามค่าเริ่มต้น หากที่ไม่ได้เป็นตัวเลือกที่strคอนสตรัคจะแปลงจาก Unicode 8 บิตดังนั้นเพียงแค่ห่วงซ้ำมากกว่าผลและแปลงไปunicode strอย่างไรก็ตามมันอาจจะดีที่สุดเพียงปล่อยให้สตริงเป็น Unicode


8

Unicode เป็นประเภทที่เหมาะสมที่นี่ เอกสาร JSONDecoder อธิบายตารางการแปลงและสถานะที่วัตถุสตริง json ถูกถอดรหัสเป็นวัตถุ Unicode

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

"การเข้ารหัสกำหนดการเข้ารหัสที่ใช้ในการแปลความหมายของวัตถุ str ที่ถอดรหัสโดยอินสแตนซ์นี้ (UTF-8 ตามค่าเริ่มต้น)"


7

อักขระ 'u' เหล่านั้นที่ถูกผนวกเข้ากับวัตถุหมายถึงว่าวัตถุนั้นถูกเข้ารหัสใน "unicode"

หากคุณต้องการลบตัวอักษร 'u' เหล่านั้นออกจากวัตถุของคุณคุณสามารถทำได้:

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

มาเช็คเอาจากเปลือกหลาม

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

ฉันขอแนะนำให้ newbie ทุกคนลองใช้สคริปต์นี้และ voila คุณมีสคริปต์ในการแปลง ~ จาก ~ u'JSON เอาท์พุท :) ... หากมีเพียงสามารถเพิ่ม stdin ให้กับสคริปต์และรูปแบบ json ในตอนท้ายคุณเป็น พร้อมที่จะไป!
Jordan Gee

4

ฉันยังคงพบปัญหานี้เมื่อพยายามจับข้อมูล JSON ในบันทึกด้วยloggingไลบรารีPython เพื่อการดีบักและแก้ไขปัญหา การรับuตัวละครเป็นเรื่องน่ารำคาญจริง ๆ เมื่อคุณต้องการคัดลอกข้อความและวางลงในโค้ดของคุณ

อย่างที่ทุกคนจะบอกคุณนี่เป็นเพราะมันเป็น Unicode ที่เป็นตัวแทนและมันอาจมาจากข้อเท็จจริงที่ว่าคุณเคยjson.loads()โหลดข้อมูลจากสตริงในตอนแรก

หากคุณต้องการให้ตัวแทน JSON ในบันทึกโดยไม่มีuคำนำหน้าเคล็ดลับคือการใช้json.dumps()ก่อนออกจากระบบ ตัวอย่างเช่น:

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
นี่น่าจะเป็นคำตอบที่ดีที่สุดคำว่า 'u ไม่ได้ "ถูกถอดออก" ในหลายบริบท ขอบคุณมากสำหรับเรื่องนี้!
เจสสิก้าเพนเนล

1

ลองสิ่งนี้:

mail_accounts [0] .encode ( "ASCII")


คำตอบที่ไม่มีคำอธิบายใด ๆ นั้นเกือบจะไร้ประโยชน์ โปรดลองเพิ่มข้อมูลเช่นนี้จะช่วยได้
Abhilash Chandran

โดยส่วนตัวแล้วฉันพบคำตอบยาว ๆ ที่มีข้อมูลที่ไม่จำเป็นรบกวนมากเกินไป คำตอบข้างต้นอธิบายไว้แล้วว่าค่าเป็น Unicode และจำเป็นต้องแปลงเป็น ASCII ดังนั้นฉันไม่ได้ทำซ้ำทั้งหมด เพียงแสดงวิธีที่ง่ายกว่าในการรับค่า หากใครมีปัญหาในการใช้คำตอบนี้เพียงแค่ถามและฉันยินดีที่จะอธิบายเพิ่มเติม! ขอขอบคุณ
2nd Sight Lab

นี่เป็นคำตอบเดียวที่แสดงให้เห็นอย่างชัดเจนว่าจะเขียนโค้ดแต่ละสตริงเป็น 'ปกติ' ได้อย่างไรโดยไม่ต้องผ่าน a (สิ่งที่ต้องไม่มีประสิทธิภาพอย่างน่าขัน) json.loads, json.dumps cycle
Ed Randall

0

เพียงแทนที่คุณด้วยเครื่องหมายคำพูดเดียว ...

print (str.replace(mail_accounts,"u'","'"))
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.