2009-08-10 4 views
67

मुझे कोड की एक "परत" से एक नियम प्राप्त हो रहा है जिस पर कुछ गणना/संशोधन इसे किसी अन्य "परत" पर जाने से पहले किया जाता है। मूल dict की कुंजी & "स्ट्रिंग" मान unicode हैं, लेकिन वे जिस परत को पारित कर रहे हैं वह केवल str स्वीकार करता है।'यूनिकोड` से' str` तक एक dict की कुंजी और मानों को परिवर्तित करने का सबसे तेज़ तरीका?

इस बार कहा जा रहा है, तो मैं पता है कि सबसे तेज़ तरीका है की तरह कुछ परिवर्तित करने के लिए किया जाएगा चाहते हैं:

{ u'spam': u'eggs', u'foo': True, u'bar': { u'baz': 97 } } 

... करने के लिए:

{ 'spam': 'eggs', 'foo': True, 'bar': { 'baz': 97 } } 

। .. ध्यान में रखते हुए गैर- "स्ट्रिंग" मानों को उनके मूल प्रकार के रूप में रहने की आवश्यकता है।

कोई विचार?

उत्तर

133
DATA = { u'spam': u'eggs', u'foo': frozenset([u'Gah!']), u'bar': { u'baz': 97 }, 
     u'list': [u'list', (True, u'Maybe'), set([u'and', u'a', u'set', 1])]} 

def convert(data): 
    if isinstance(data, basestring): 
     return str(data) 
    elif isinstance(data, collections.Mapping): 
     return dict(map(convert, data.iteritems())) 
    elif isinstance(data, collections.Iterable): 
     return type(data)(map(convert, data)) 
    else: 
     return data 

print DATA 
print convert(DATA) 
# Prints: 
# {u'list': [u'list', (True, u'Maybe'), set([u'and', u'a', u'set', 1])], u'foo': frozenset([u'Gah!']), u'bar': {u'baz': 97}, u'spam': u'eggs'} 
# {'bar': {'baz': 97}, 'foo': frozenset(['Gah!']), 'list': ['list', (True, 'Maybe'), set(['and', 'a', 'set', 1])], 'spam': 'eggs'} 

अनुमान:

  • आप संग्रह मॉड्यूल आयात किया है और सार आधार वर्ग यह
  • प्रदान करता है आप डिफ़ॉल्ट एन्कोडिंग का उपयोग परिवर्तित करने के लिए खुश हैं का उपयोग कर सकते (data.encode('utf-8') बल्कि का उपयोग str(data) से अधिक यदि आपको एक स्पष्ट एन्कोडिंग की आवश्यकता है)।

यदि आपको अन्य कंटेनर प्रकारों का समर्थन करने की आवश्यकता है, तो उम्मीद है कि यह स्पष्ट है कि पैटर्न का पालन कैसे करें और उनके लिए केस कैसे जोड़ें।

+0

और कुछ मूल्य क्या हैं यदि कुछ मूल्य सूचियां/सेट/आदि हैं? –

+0

@ फिलिप: उनके लिए मामले जोड़ें। उत्तर अपडेट किया गया, और फिर कंटेनरों के भीतर घोंसले के कंटेनरों के लिए फिर से अपडेट किया गया। – RichieHindle

+1

आप ट्यूपल और फ्रोजनसेट भूल गए, रिची – SilentGhost

3
def to_str(key, value): 
    if isinstance(key, unicode): 
     key = str(key) 
    if isinstance(value, unicode): 
     value = str(value) 
    return key, value 

पास कुंजी और मूल्य, और आंतरिक कोड के लिए आपके कोड में रिकर्सन जोड़ें।

12

, तो आप इस इनलाइन करना चाहता था और पुनरावर्ती वंश जरूरत नहीं थी, इस काम हो सकता है:

DATA = { u'spam': u'eggs', u'foo': True, u'bar': { u'baz': 97 } } 
print DATA 
# "{ u'spam': u'eggs', u'foo': True, u'bar': { u'baz': 97 } }" 

STRING_DATA = dict([(str(k), v) for k, v in data.items()]) 
print STRING_DATA 
# "{ 'spam': 'eggs', 'foo': True, 'bar': { u'baz': 97 } }" 
+4

2.7 के लिए और इसके बाद इसे निम्नानुसार सरल बनाया जा सकता है : '{str (key): कुंजी के लिए मान, data.items()}' – AnjoMan

19

मैं जानता हूँ कि मैं इस पर देर हो रही है: एक गैर के लिए

def convert_keys_to_string(dictionary): 
    """Recursively converts dictionary keys to strings.""" 
    if not isinstance(dictionary, dict): 
     return dictionary 
    return dict((str(k), convert_keys_to_string(v)) 
     for k, v in dictionary.items()) 
+1

Yup में मान, यह ऐसा करने का सही तरीका प्रतीत होता है, इनलाइन और अन्य संस्करण वास्तव में असली दुनिया परिदृश्यों के लिए पर्याप्त नहीं हैं। बुरा यह पूरा करने के लिए कोई भरोसेमंद इनलाइन रिकर्सनलेस तरीका नहीं है। या शायद पाइथन स्ट्र (...) जेसन सम्मेलनों पर आधारित है? – jayunit100

+1

यह मेरा पसंदीदा है, केवल चाबियाँ बदलने के लिए, जो मैं ढूंढ रहा था। छोटे टाइपो : आपको वापस दिए गए dict() तर्क के चारों ओर एक अतिरिक्त() की आवश्यकता है। – ggll

+0

धन्यवाद आदमी। सभी अच्छे और काम कर रहे हैं। चीयर्स !! – ashim888

2

-निस्टेड dict (क्योंकि शीर्षक उस मामले का उल्लेख नहीं करता है, यह अन्य लोगों के लिए दिलचस्प हो सकता है)

{str(k): str(v) for k, v in my_dict.items()} 
+1

{str (k): str (v) k के लिए v, v my_dict.items()} में –

2

इसे सभी इनलाइन बनाने के लिए ई (गैर-पुनरावर्ती):

{str(k):(str(v) if isinstance(v, unicode) else v) for k,v in my_dict.items()} 
संबंधित मुद्दे