Python: json.loads trả về các mục có tiền tố với 'u'


161

Tôi sẽ nhận được một chuỗi mã hóa JSON Obj-C và tôi đang giải mã một chuỗi giả (hiện tại) như mã dưới đây. Đầu ra của tôi xuất hiện với ký tự 'u' tiền tố mỗi mục:

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

JSON thêm char unicode này như thế nào? Cách tốt nhất để loại bỏ nó là gì?

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 có một vấn đề ở đây. Mọi thứ không lạnh. Tôi đang gặp lỗi trong chuỗi mà Python tạo khi tôi thử và ghi các chuỗi này vào một tệp. Ví dụ: khi python lấy "53" từ JSON, nó biến nó thành u'53 'và cố gắng ghi nó vào một tệp dưới dạng ký tự hex u' \ xe1 ', khiến Python lấy một chuỗi hoàn toàn tốt và đánh lừa nó: JSON: {"sa_BstDeAv": "53", "sa_BwVUpMx" ... PYTHON: {u'sa_BstDeAv ': u'53', u'sa_BwVUpMx '... ERROR ON WRITE: Lỗi giá trị (' ascii ' ký tự u '\ xe1' ở vị trí 5: thứ tự không nằm trong phạm vi (128))
David Urry

@janehouse câu trả lời đúng ở đây là câu trả lời của jdi Tôi thực sự nghĩ bạn nên thay đổi nó.
Dekel

Câu trả lời:


168

Tiền tố chỉ có nghĩa là bạn có một chuỗi Unicode. Khi bạn thực sự sử dụng chuỗi, nó sẽ không xuất hiện trong dữ liệu của bạn. Đừng bị ném bởi đầu ra in.

Ví dụ: thử điều này:

print mail_accounts[0]["i"]

Bạn sẽ không nhìn thấy một u.


5
Câu trả lời của bạn là câu trả lời hữu ích nhất mà tôi nhận được và tôi nghĩ người hỏi câu hỏi này sẽ thực sự đánh giá cao nó: stackoverflow.com/questions/956867/
Lỗi

1
Cảm ơn bạn rất nhiều ! tôi đã bối rối vì bức thư của bạn quá lâu
ketan khandagale

Ngoại trừ nếu bạn sao chép và dán nó, bạn có một lượng lớn udữ liệu. Thành thật mà nói, in ra uđể chỉ ra đó là một chuỗi Unicode là một trong những sai lầm tồi tệ nhất về Python. Hoàn toàn vô lý. Tại sao không in một achuỗi trước mỗi chuỗi nếu đó là ASCII? Một inếu nó là một số nguyên?
Snowcrash

Trong Python 2, các chuỗi Unicode là một loại khác với các chuỗi byte, do đó, repr của dữ liệu bao gồm tiền tố để chỉ ra điều đó. Nó không phải là về nội dung xảy ra, mà là về loại. Tiền tố u vẫn ổn nếu bạn dán nội dung lại vào chương trình Python. Nếu không, có lẽ bạn muốn sử dụng json.dumps () thay thế.
Ned Batchelder

Bạn phải sử dụng chuỗi để tìm kiếm từ điển của json. tuy nhiên bạn không thể sử dụng toán tử dấu chấm.
Maddocks

151

Mọi thứ đều tuyệt, anh bạn. 'U' là một điều tốt, nó chỉ ra rằng chuỗi có kiểu Unicode trong python 2.x.

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


71
Tôi thích giai điệu rất lạnh của cái này. +1 cho câu trả lời (đúng) khiến tôi mỉm cười.
mgilson

19
Chỉ là, ớn lạnh ... (┛◉┛◉◉) 彡
┻ ┻

31
Đó là câu trả lời thư giãn nhất mà tôi đã đọc trên StackOverflow.
aanrv

3
☮ Hòa bình ☮ ☮
sr9yar 17/12/18

54

Các d3 in dưới đây là bản bạn đang tìm kiếm (là sự kết hợp giữa bãi và tải) :)

Đang có:

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

Bản in:

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
Huh? json.dumpschuyển đổi dict trở lại chuỗi (được mã hóa JSON). Đó không phải là điều OP muốn làm. -1.
Đánh dấu Amery

10
Nhưng nếu bạn sử dụng nó cùng với json.loads thì nó xuất ra từ điển mà không có các ký tự được mã hóa wihch là một câu trả lời cho câu hỏi (đây là bản in d3 ở trên) hãy đọc câu trả lời tốt!
Sao Thủy

8

Các uphương tiện prefix rằng những chuỗi là unicode chứ không phải là chuỗi 8-bit. Cách tốt nhất để không hiển thị utiền tố là chuyển sang Python 3, trong đó các chuỗi là unicode theo mặc định. Nếu đó không phải là một tùy chọn, hàm strtạo sẽ chuyển đổi từ unicode thành 8 bit, do đó, chỉ cần lặp lại đệ quy qua kết quả và chuyển đổi unicodethành str. Tuy nhiên, tốt nhất là chỉ để lại các chuỗi là unicode.


8

Unicode là một loại thích hợp ở đây. Các tài liệu JSONDecoder mô tả bảng chuyển đổi và nói rằng các đối tượng chuỗi json được giải mã thành các đối tượng Unicode

https://docs.python.org/2/l 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

"mã hóa xác định mã hóa được sử dụng để giải thích bất kỳ đối tượng str nào được giải mã theo trường hợp này (UTF-8 theo mặc định)."


7

Các ký tự 'u' được thêm vào một đối tượng biểu thị rằng đối tượng được mã hóa thành "unicode".

Nếu bạn muốn xóa các ký tự 'u' khỏi đối tượng của mình, bạn có thể thực hiện việc này:

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

Hãy kiểm tra từ vỏ trăn

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

Tôi đề nghị mọi người mới chỉ cần thử tập lệnh này và voila bạn có cho mình một tập lệnh để chuyển đổi ~ từ ~ u'JSON output :) ... nếu cuối cùng chỉ có thể thêm stdin vào tập lệnh và định dạng json sẵn sàng để đi!
Jordan Gee

4

Tôi tiếp tục gặp vấn đề này khi cố gắng thu thập dữ liệu JSON trong nhật ký với loggingthư viện Python , nhằm mục đích gỡ lỗi và khắc phục sự cố. Bắt unhân vật là một phiền toái thực sự khi bạn muốn sao chép văn bản và dán nó vào mã của bạn ở đâu đó.

Như mọi người sẽ nói với bạn, điều này là do nó là một đại diện Unicode và nó có thể xuất phát từ thực tế là bạn đã sử dụng json.loads()để tải dữ liệu từ một chuỗi ở vị trí đầu tiên.

Nếu bạn muốn biểu diễn JSON trong nhật ký, không có utiền tố, mẹo là sử dụng json.dumps()trước khi đăng xuất. Ví dụ:

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
Đây thực sự nên là câu trả lời tốt nhất, 'bạn hoàn toàn không "bị tước đoạt" trong nhiều bối cảnh. Cám ơn bạn rất nhiều về điều này.
Jessica Pennell

1

Thử cái này:

mail_accounts [0] .encode ("ascii")


Một câu trả lời mà không có lời giải thích là gần như vô dụng. Hãy cố gắng thêm một số thông tin như tại sao điều này sẽ giúp.
Abhilash Chandran

Cá nhân, tôi tìm thấy câu trả lời dài với quá nhiều thông tin không cần thiết gây mất tập trung. Các câu trả lời ở trên đã giải thích rằng giá trị là unicode và cần được chuyển đổi thành ascii vì vậy tôi không lặp lại tất cả. Chỉ cần hiển thị một cách đơn giản hơn để có được giá trị. Nếu bất cứ ai có vấn đề sử dụng câu trả lời này chỉ cần hỏi và tôi rất vui lòng giải thích thêm! Cảm ơn
Phòng thí nghiệm thứ 2

Đây thực sự là câu trả lời duy nhất chỉ ra cách chính xác cách mã hóa lại từng chuỗi thành 'bình thường' mà không cần thông qua một chu trình json.loads, json.dumps.
Ed Randall

0

Chỉ cần thay thế u 'bằng một trích dẫn duy nhất ...

print (str.replace(mail_accounts,"u'","'"))
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.