Est यूनिकोड ’से? स्ट्रै’ तक एक तानाशाही कुंजी और मूल्यों को परिवर्तित करने का सबसे तेज़ तरीका?


81

मुझे कोड की एक "परत" से एक तानाशाह प्राप्त हो रहा है, जिस पर कुछ गणना / संशोधन दूसरे "परत" पर पारित होने से पहले किए जाते हैं। मूल तानाशाही की चाबियाँ और "स्ट्रिंग" मान हैं unicode, लेकिन वे जिस परत को पारित कर रहे हैं वह केवल स्वीकार करता है str

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

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

...सेवा:

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

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

कोई विचार?

जवाबों:


151
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)यदि आपको स्पष्ट एन्कोडिंग की आवश्यकता है)।

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


और अगर कुछ मान सूची / सेट / आदि हैं तो कोई क्या करेगा?
फिलिप बी ओल्डम

1
आप टुपल और फ्रेज़ेन्सेट, रिची
साइलेंटगॉस्ट

3
आप type(data)(map(convert, data))इसके बजाय क्यों इस्तेमाल करते हैं map(convert, data)?
अब्बासोव अलेक्जेंडर

4
@AbbasovAlexander: ताकि आप वापस उसी तरह से प्राप्त करें जैसे आप में डालते हैं - एक ट्यूपल टपल बन जाता है, एक सूची एक सूची बन जाती है, एक सेट बन जाता है, और इसी तरह।
रिचीहिंडल जूल

1
@Moberg: केवल तभी जब आपके डेटा संरचना में कई सैकड़ों स्तर गहरे हों।
रिचीहिंडल

25

मुझे पता है कि मुझे इस पर देर हो रही है:

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
हाँ, यह ऐसा करने का सही तरीका लगता है, इनलाइन और अन्य संस्करण वास्तव में वास्तविक दुनिया के परिदृश्य के लिए पर्याप्त नहीं हैं। बहुत बुरा यह पूरा करने के लिए कोई विश्वसनीय इनलाइन पुनरावृत्तिहीन तरीका है। या हो सकता है कि वहाँ अजगर str (...) json सम्मेलनों पर आधारित हो?
jayunit100

1
यह मेरी पसंदीदा है, केवल कुंजियों को बदलने के लिए, जो कि मैं देख रहा था। छोटे टाइपो: आपको उस अतिरिक्त () तर्क के चारों ओर एक () तर्क चाहिए जो वापस आ गया है।
ggll

इस समाधान के साथ एकमात्र समस्या यह है कि यदि आपकी चाबियाँ सभी तार नहीं हैं (यानी इंट प्रकार)
MrWonderful

@ गंभीर और ऐसा क्यों है? मैं किसी strइंट में कॉल करने में कोई समस्या नहीं देख सकता
जर्मनो

@ Gemo: बेशक आप एक int पर str () कॉल कर सकते हैं, लेकिन आपको एक str मिलता है .... एक int नहीं। तो कुंजी का प्रकार एक इंट से एक str में बदल जाएगा, जो यूनिकोड को str से अधिक बदलने से अधिक है - मूल प्रश्न।
MrWonderful

13

यदि आप इस इनलाइन को करना चाहते हैं और पुनरावर्ती वंश की आवश्यकता नहीं है, तो यह काम कर सकता है:

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
{ str(key):value for key,value in data.items() }
२. can

4

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

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

1
{str (के): कश्मीर के लिए str (v), my_dict.items में वी ()}
yardstick17

इससे मेरी कुंजियों को स्ट्रिंग्स में बदलने में मदद मिली, जिसकी मुझे अपने डेटाफ़्रेम कॉलम
मेगामाइंड

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

कुंजी और मान को पास करें, और अपने कोड में आंतरिक शब्दकोश के लिए पुनरावर्तन जोड़ें।


2

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

{str(k):(str(v) if isinstance(v, unicode) else v) for k,v in my_dict.items()}

0

महज प्रयोग करें print(*(dict.keys()))

* कंटेनर को अनपैकिंग कंटेनर जैसे सूचियों के लिए इस्तेमाल किया जा सकता है। * पर अधिक जानकारी के लिए इस एसओ उत्तर की जाँच करें


हालाँकि यह कोड समस्या को हल कर सकता है, एक अच्छे उत्तर में यह बताना चाहिए कि कोड क्या करता है और यह कैसे मदद करता है।
बीडीएल

0
>>> d = {u"a": u"b", u"c": u"d"}
>>> d
{u'a': u'b', u'c': u'd'}
>>> import json
>>> import yaml
>>> d = {u"a": u"b", u"c": u"d"}
>>> yaml.safe_load(json.dumps(d))
{'a': 'b', 'c': 'd'}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.