शब्दकोश में एक शब्दकोश के एक स्ट्रिंग प्रतिनिधित्व कन्वर्ट?


767

मैं निम्नलिखित स्ट्रिंग जैसे stra के प्रतिनिधित्व को कैसे परिवर्तित कर सकता हूं ?dictdict

s = "{'muffin' : 'lolz', 'foo' : 'kitty'}"

मैं उपयोग नहीं करना पसंद करता हूं eval। मैं और क्या उपयोग कर सकता हूं?

इसका मुख्य कारण, मेरे सहकर्मी वर्गों में से एक है जो उन्होंने लिखा था, सभी इनपुट को तार में परिवर्तित करता है। मैं इस समस्या से निपटने के लिए, अपनी कक्षाओं को जाने और संशोधित करने के मूड में नहीं हूं।


1
यदि आप पाइथन 2.6 का उपयोग नहीं कर सकते हैं, तो आप कोड.activestate.com/recipes/364469 जैसे सिंपल सफेवल इम्प्लांटेशन का उपयोग कर सकते हैं। यह पाइथन कंपाइलर पर पिग्गीबैक होता है, इसलिए आपको सभी सकल काम खुद करने की जरूरत नहीं है।
नेड बैचेल्ड

11
नोट : उन लोगों के लिए जो भ्रामक रूप से समान JSON डेटा के साथ यहां आते हैं , आप पाइथन में Parse JSON पढ़ने के बजाय जाना चाहते हैं । JSON पायथन के समान नहीं है । यदि आपके पास "आपके स्ट्रिंग्स के आसपास दोहरे उद्धरण-चिह्न हैं, तो संभवतः आपके पास JSON डेटा है। तुम भी null, trueया false, पायथन सिंटैक्स का उपयोग कर सकते हैं None, Trueऔर False
मार्टिन पीटर्स

जवाबों:


1167

पायथन 2.6 में शुरू आप बिल्ट-इन का उपयोग कर सकते हैं ast.literal_eval:

>>> import ast
>>> ast.literal_eval("{'muffin' : 'lolz', 'foo' : 'kitty'}")
{'muffin': 'lolz', 'foo': 'kitty'}

यह उपयोग करने से अधिक सुरक्षित है eval। जैसा कि इसके स्वयं के डॉक्स कहते हैं:

>>> मदद (ast.literal_eval)
मॉड्यूल में फ़ंक्शन शाब्दिक_लव पर मदद करें ast:

literal_eval (node_or_string)
    सुरक्षित रूप से एक अभिव्यक्ति नोड या एक पायथन युक्त स्ट्रिंग का मूल्यांकन करें
    अभिव्यक्ति। प्रदान की गई स्ट्रिंग या नोड में केवल निम्नलिखित शामिल हो सकते हैं
    पायथन शाब्दिक संरचनाएँ: तार, संख्याएँ, टुपल्स, सूचियाँ, डाइक, बूलियन,
    और कोई नहीं।

उदाहरण के लिए:

>>> eval("shutil.rmtree('mongo')")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1, in <module>
  File "/opt/Python-2.6.1/lib/python2.6/shutil.py", line 208, in rmtree
    onerror(os.listdir, path, sys.exc_info())
  File "/opt/Python-2.6.1/lib/python2.6/shutil.py", line 206, in rmtree
    names = os.listdir(path)
OSError: [Errno 2] No such file or directory: 'mongo'
>>> ast.literal_eval("shutil.rmtree('mongo')")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/Python-2.6.1/lib/python2.6/ast.py", line 68, in literal_eval
    return _convert(node_or_string)
  File "/opt/Python-2.6.1/lib/python2.6/ast.py", line 67, in _convert
    raise ValueError('malformed string')
ValueError: malformed string

मुझे जोड़ना चाहिए कि आपको ast.literal_eval के साथ उपयोग के लिए स्ट्रिंग को साफ करने की आवश्यकता है। (सुनिश्चित करें कि स्ट्रिंग में उद्धरण / दोहरे उद्धरण बच गए हैं)
पाउलो माटोस

मुझे यह त्रुटि मिलती है मैं विंडोज़ 7 x64 फ़ाइल "डी: \ Python26 \ lib \ ast.py", लाइन 48 पर, शाब्दिक_में नोड_र_स्ट्रिंग = पार्स (नोड_ओर_स्ट्रिंग, मोड = 'एवैल') फ़ाइल "डी" पर "पायथन 2.6 (x86) पर हूं। : \ Python26 \ lib \ ast.py ", पंक्ति 36, पार्स रिटर्न कंपाइल में (एक्सप, फाइल, मोड, PyCF_ONLY_AST) फ़ाइल" <अज्ञात> ", पंक्ति 1 ^ सिंटैक्सऑर्डर: अमान्य सिंटैक्स

"dict(a=1)"स्टाइल स्ट्रिंग्स के बारे में क्या ?
n611x007

यह एक शब्दकोश के अंदर एनम मूल्य के लिए काम करने के लिए प्रतीत नहीं होता है। जैसे: d = "{'col': <Colors.RED: 2>, 'val': 2}"
shivshnkr

3
json.dumps और json.loads का उपयोग क्यों नहीं करते हैं, मैं इस समाधान को eval का उपयोग करते हुए अधिक ऊंचाई से पाया
Auros132

232

https://docs.python.org/3.8/library/json.html

JSON इस समस्या को हल कर सकता है, हालांकि इसका डिकोडर कुंजी और मूल्यों के आसपास दोहरे उद्धरण चिह्नों को चाहता है। यदि आप एक हैक की जगह बुरा नहीं है ...

import json
s = "{'muffin' : 'lolz', 'foo' : 'kitty'}"
json_acceptable_string = s.replace("'", "\"")
d = json.loads(json_acceptable_string)
# d = {u'muffin': u'lolz', u'foo': u'kitty'}

ध्यान दें कि यदि आपके पास अपनी कुंजियों या मूल्यों के हिस्से के रूप में एकल उद्धरण हैं तो यह अनुचित चरित्र प्रतिस्थापन के कारण विफल हो जाएगा। यह समाधान केवल तभी सुझाया जाता है, जब आपके पास eval solution के लिए एक मजबूत हिमस्खलन हो।

Json सिंगल कोट्स के बारे में अधिक जानकारी: jQuery.parseJSON थ्रेड में एकल उद्धरण से बचने के कारण "अमान्य JSON" त्रुटि फेंकता है



4
{'foo': (1, 2, 3)}
मार्क ई। हासे

1
मैं इस समाधान की तलाश में था। +1यह बताने के लिए कि डिकोडर कुंजी और मूल्यों के आसपास डबल उद्धरण चाहता है।
h8pathak

एक अन्य समस्या के लिए है "{0: 'Hello'}"
फिन Finरूप नीलसन

3
यह भी विफल हो जाता है यदि आपके पास ट्रेलिंग कॉमा (नहीं JSON कंप्लेंट) है, जैसे: "{'मफिन': 'लोलज़', 'फू': 'किटी',}"
प्रतिद्वंद्वी

159

का उपयोग कर json.loads:

>>> import json
>>> h = '{"foo":"bar", "foo2":"bar2"}'
>>> d = json.loads(h)
>>> d
{u'foo': u'bar', u'foo2': u'bar2'}
>>> type(d)
<type 'dict'>

13
मुझे नहीं लगता कि यह ओपी के जवाब का जवाब देता है। हम एक स्ट्रिंग s = "{'मफिन': 'लोल्ज', 'फू': 'किटी'}" को तानाशाही में बदलने के लिए json.laads का उपयोग कैसे करते हैं?
टेक्नाज़ी

आउटपुट में यह मुद्रण 'u' क्यों है ?? जैसे - str = '"" 1 ":" P "," 2 ":" N "," 3 ":" M "}' d = json.loads (str) प्रिंट d आउटपुट है: {u'1 ': u'P ', u'3': u'M ', u'2': u'N '}
user905

2
@technazi: json.loads (h.replace ("" ", '"'))
ntg

हालाँकि, सीमाएँ हैं, उदाहरण के लिए: h = '' "muffin": "lolz", "foo": "kitty",} ', भी h =' '"muffin's": "lolz", "foo": "kitty "} ', (एक ही जवाब में समान टिप्पणियों का हिस्सा देखा ... अभी भी पूर्णता के लिए यहाँ छोड़ रहा है ...)
ntg

4
मेरी राय में, यह सबसे छोटा और आसान तरीका है ... निश्चित रूप से वह जिसे मैं व्यक्तिगत रूप से पसंद करता हूं।
नास्त्रेदमस

35

ओपी के उदाहरण के लिए:

s = "{'muffin' : 'lolz', 'foo' : 'kitty'}"

हम स्ट्रिंग में इस तरह के गैर-मानक जोंस से निपटने के लिए यमल का उपयोग कर सकते हैं :

>>> import yaml
>>> s = "{'muffin' : 'lolz', 'foo' : 'kitty'}"
>>> s
"{'muffin' : 'lolz', 'foo' : 'kitty'}"
>>> yaml.load(s)
{'muffin': 'lolz', 'foo': 'kitty'}

1
यह 'हाँ' और 'ना' तार को ट्रू / फाल्स में
एरिक मार्कोस

23

यदि स्ट्रिंग पर हमेशा भरोसा किया जा सकता है, तो आप सुझाव के रूप में उपयोग कर सकते हैं eval(या उपयोग कर सकते हैं literal_eval; यह कोई भी बात नहीं है कि स्ट्रिंग क्या है) सुरक्षित है। अन्यथा आपको एक पार्सर की आवश्यकता है। एक JSON पार्सर (जैसे कि सिंपलसन) काम करेगा अगर वह केवल JSON योजना के साथ फिट होने वाली सामग्री को संग्रहीत करता है।


8
2.6 में शुरू, सिम्पसन को पायस मानक पुस्तकालय में जस मॉड्यूल के रूप में शामिल किया गया है।
एली कोर्टराइट

11
हाँ, यह एक अच्छा जवाब है, लेकिन ध्यान दें कि आधिकारिक तौर पर JSON एकल-उद्धृत स्ट्रिंग्स का समर्थन नहीं करता है, जैसा कि मूल पोस्टर के उदाहरण में दिया गया है।
बेन होयट

19

का उपयोग करें jsonastपुस्तकालय स्मृति का एक बहुत और और धीमी खपत करता है। मेरे पास एक प्रक्रिया है जिसे 156Mb की एक पाठ फ़ाइल को पढ़ने की आवश्यकता है। Astरूपांतरण शब्दकोश के लिए 5 मिनट की देरी jsonऔर 60% कम मेमोरी का उपयोग करके 1 मिनट!


13
लेकिन इसकी सीमाएं हैं: स्ट्रिंग को {{'foo': 'बार',} "
ntg

12

संक्षेप में:

import ast, yaml, json, timeit

descs=['short string','long string']
strings=['{"809001":2,"848545":2,"565828":1}','{"2979":1,"30581":1,"7296":1,"127256":1,"18803":2,"41619":1,"41312":1,"16837":1,"7253":1,"70075":1,"3453":1,"4126":1,"23599":1,"11465":3,"19172":1,"4019":1,"4775":1,"64225":1,"3235":2,"15593":1,"7528":1,"176840":1,"40022":1,"152854":1,"9878":1,"16156":1,"6512":1,"4138":1,"11090":1,"12259":1,"4934":1,"65581":1,"9747":2,"18290":1,"107981":1,"459762":1,"23177":1,"23246":1,"3591":1,"3671":1,"5767":1,"3930":1,"89507":2,"19293":1,"92797":1,"32444":2,"70089":1,"46549":1,"30988":1,"4613":1,"14042":1,"26298":1,"222972":1,"2982":1,"3932":1,"11134":1,"3084":1,"6516":1,"486617":1,"14475":2,"2127":1,"51359":1,"2662":1,"4121":1,"53848":2,"552967":1,"204081":1,"5675":2,"32433":1,"92448":1}']
funcs=[json.loads,eval,ast.literal_eval,yaml.load]

for  desc,string in zip(descs,strings):
    print('***',desc,'***')
    print('')
    for  func in funcs:
        print(func.__module__+' '+func.__name__+':')
        %timeit func(string)        
    print('')

परिणाम:

*** short string ***

json loads:
4.47 µs ± 33.4 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
builtins eval:
24.1 µs ± 163 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
ast literal_eval:
30.4 µs ± 299 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
yaml load:
504 µs ± 1.29 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

*** long string ***

json loads:
29.6 µs ± 230 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
builtins eval:
219 µs ± 3.92 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
ast literal_eval:
331 µs ± 1.89 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
yaml load:
9.02 ms ± 92.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

निष्कर्ष: json.loads को प्राथमिकता दें


5
सिवाय इसके कि वह अपने एकल-उद्धृत स्ट्रिंग के साथ काम नहीं करेगा, जो उसकी प्रारंभिक समस्या का हिस्सा था। प्रदर्शन का कभी उल्लेख नहीं किया गया।
माइकल कैंपबेल

1
वाह .... सुपर एक्सप्लोरेशन ....
स्मैक चेरी

5
string = "{'server1':'value','server2':'value'}"

#Now removing { and }
s = string.replace("{" ,"")
finalstring = s.replace("}" , "")

#Splitting the string based on , we get key value pairs
list = finalstring.split(",")

dictionary ={}
for i in list:
    #Get Key Value pairs separately to store in dictionary
    keyvalue = i.split(":")

    #Replacing the single quotes in the leading.
    m= keyvalue[0].strip('\'')
    m = m.replace("\"", "")
    dictionary[m] = keyvalue[1].strip('"\'')

print dictionary

3
इस दृष्टिकोण में कई गलतियाँ। क्या होगा यदि एक कुंजी का मूल्य होता है {या }। अगर यह घोंसला है तो क्या होगा dict। क्या होगा अगर मूल्य शामिल है ,??
ओम साओ

4

कोई भी लिब का उपयोग नहीं किया जाता है:

dict_format_string = "{'1':'one', '2' : 'two'}"
d = {}
elems  = filter(str.isalnum,dict_format_string.split("'"))
values = elems[1::2]
keys   = elems[0::2]
d.update(zip(keys,values))

नोट: जैसा कि इसमें हार्डकोड किया गया है, यह split("'")केवल उन स्ट्रिंग्स के लिए काम करेगा जहां डेटा "सिंगल कोटेड" है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.