नेस्टेड शब्दकोशों को सुंदर प्रिंट कैसे करें?


289

मैं पायथन में ~ 4 की गहराई के साथ एक शब्दकोश कैसे प्रिंट कर सकता हूं? मैंने इसके साथ बहुत मुद्रण की कोशिश की pprint(), लेकिन यह काम नहीं किया:

import pprint 
pp = pprint.PrettyPrinter(indent=4)
pp.pprint(mydict)

मैं बस "\t"प्रत्येक घोंसले के शिकार के लिए एक इंडेंटेशन ( ) चाहता हूं , ताकि मुझे कुछ ऐसा मिल जाए:

key1
    value1
    value2
    key2
       value1
       value2

आदि।

मैं यह कैसे कर सकता हूँ?


29
"काम नहीं किया" क्या मतलब है? कृपया बहुत सटीक निर्दिष्ट करें कि कैसे "" काम नहीं किया।
S.Lott

5
मैंने अब इनमें से 3 उत्तरों का उपयोग किया है (प्रत्येक विशिष्ट परिदृश्य में अच्छा है): @ केन का json उत्तर अच्छा है, लेकिन कभी-कभी विफल रहता है जब ऑब्जेक्ट को जार्स क्रिएटिबल नहीं किया जा सकता है (अपवाद को फेंकता है)। यदि @ केन का json उत्तर काम नहीं करता है, तो @ एंडी के yaml उत्तर की कोशिश करता है और उसे काम करना चाहिए लेकिन स्ट्रिंग आउटपुट थोड़ा कम मानवीय है। [@ sth का उत्तर] सबसे सामान्य है (किसी भी वस्तु के लिए काम करना चाहिए और किसी भी लिबास का उपयोग नहीं करना चाहिए)।
ट्रेवर बॉयड स्मिथ

जवाबों:


143

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

def pretty(d, indent=0):
   for key, value in d.items():
      print('\t' * indent + str(key))
      if isinstance(value, dict):
         pretty(value, indent+1)
      else:
         print('\t' * (indent+1) + str(value))

8
यू पता @ केन का पारंपरिक उत्तर इससे बेहतर है। Json पहले से ही सब कुछ संभालता है और इस तरह की त्रुटियां दे सकता है: UnicodeEncodeError: 'ascii' कोडक चरित्र u '\ xf3' को 50 की स्थिति में सांकेतिक शब्दों में बदलना नहीं कर सकता है:
क्रमांक

मैं इसे अपने समाधान के नेस्टेड तानाशाह के साथ काम नहीं कर सकता, क्योंकि इसने मुझे एक यूनिकोडेकोडकोड प्रदान किया है, यह भी प्रमुख कुंजी को प्रिंट नहीं करता है, सूची और ट्यूपल्स के अंदर न जाएं और एक अजगर मान्य सिंटैक्स न रखें।
y.petremann

इस जवाब ने मेरे लिए एक आकर्षण की तरह काम किया, हालाँकि मैंने एक नया प्रश्न stackoverflow.com/questions/36972225/… पोस्ट किया है, जो इस बात की सीमा तय करता है कि कितने मान छापे जाने चाहिए।
gsamaras

काफी अच्छा। यदि आपको ओपी के प्रश्न में नेस्टेड सूची मिली है, तो आपको उसके लिए कुछ हैंडलिंग जोड़ने की आवश्यकता है। यदि आप Py2 में समस्याएँ हैं, तो इसका कारण यह है कि यह यूनिकोड को ठीक से हैक किए बिना ठीक से संभाल नहीं सकता है जैसे __future__कि अब उत्तर का उल्लेख है, इसलिए आपको जहाँ भी आवश्यक हो उन्हें नियोजित करना होगा (या पहले से ही 3 पर अपडेट करें)।
सूडो

इसने मेरे लिए काफी अच्छा काम किया: python def pretty(d, indent=0): for key, value in d.items(): if isinstance(value, dict): print(' ' * indent + str(key)) pretty(value, indent+1) else: print(' ' * (indent+1) + f"{key}: {value}")
hum3

500

मेरा पहला विचार यह था कि JSON धारावाहिक शायद नेस्टेड शब्दकोशों में बहुत अच्छा है, इसलिए मैं उसे धोखा दूँगा और उसका उपयोग करूंगा:

>>> import json
>>> print json.dumps({'a':2, 'b':{'x':3, 'y':{'t1': 4, 't2':5}}},
...                  sort_keys=True, indent=4)
{
    "a": 2,
    "b": {
        "x": 3,
        "y": {
            "t1": 4,
            "t2": 5
        }
    }
}

41
यह अच्छा है, लेकिन सभी शब्दकोशों को अच्छी तरह से प्रिंट नहीं करता है। प्रिंट json.dumps (myObject .__ dict__, Sort_keys = True, indent = 4) # टाइप करें: <ऑब्जेक्ट 0x0000000002E6A748 पर> JSON
सीरियलसेबल

4
हालांकि यह उपयोगी दिखता है, यह आउटपुट वही है जो ओपी चाहता था।
मार्टिअन

2
@martineau: ओपी के अनुरोधित आउटपुट का कोई मतलब नहीं है, शब्दकोशों को प्रति मूल्य कुंजी की आवश्यकता है।
n

2
@ naught101: एक सुंदर प्रिंटर वांछित उत्पादन करने के लिए जो कुछ भी आवश्यक है वह कर सकता है।
7

22
json.dumps वैकल्पिक रूपांतरण के रूप में रूपांतरण फ़ंक्शन लेता है, इसलिए json.dumps (myObject .__ dict__, Sort_keys = True, indent = 4, deault = str) के साथ आप कम से कम खुद को प्रिंट करने और गोल पाने के लिए repr के ऑब्जेक्ट कार्यान्वयन का उपयोग कर सकते हैं। '
जेएसएन

56

आप की कोशिश कर सकते YAML के माध्यम से PyYAML । इसका आउटपुट ठीक-ठाक हो सकता है। मैं निम्नलिखित के साथ शुरू करने का सुझाव देता हूं:

print yaml.dump(data, allow_unicode=True, default_flow_style=False)

परिणाम बहुत पठनीय है; जरूरत पड़ने पर इसे पायथन में वापस भी भेजा जा सकता है।

संपादित करें:

उदाहरण:

>>> import yaml
>>> data = {'a':2, 'b':{'x':3, 'y':{'t1': 4, 't2':5}}}
>>> print yaml.dump(data, default_flow_style=False)
a: 2
b:
  x: 3
  y:
    t1: 4
    t2: 5

1
याम्ल का उपयोग करना बहुत दिलचस्प है क्योंकि यह डेटा प्रकार को अपने प्रारूप पर रखता है, केवल एक चीज जो मैं इसके खिलाफ कह सकता हूं वह यह है कि यह एक मान्य अजगर स्ट्रिंग का उत्पादन नहीं करता है, लेकिन लगभग अजगर में परिवर्तित किया जा सकता है।
y.petremann

1
YAML अदिश प्रकार के Numpy के संस्करण की तरह नहीं है ... मैं हैरान नहीं किया गया है कि NumPy सरणी का समर्थन नहीं करता है, लेकिन मैं एक के लिए एक ही उत्पादन की उम्मीद है | floatऔर एकnumpy.float64
PhilMacKay

इस दृष्टिकोण ने मेरे लिए शब्दकोशों की सूची का उपयोग करके भी काम किया
ग्रांट शैनन

36

जैसा कि किया गया है, मुझे ऐसा कोई सुंदर प्रिंटर दिखाई नहीं देता है जो कम से कम बहुत सरल स्वरूपण के साथ अजगर दुभाषिया के उत्पादन की नकल करता है:

class Formatter(object):
    def __init__(self):
        self.types = {}
        self.htchar = '\t'
        self.lfchar = '\n'
        self.indent = 0
        self.set_formater(object, self.__class__.format_object)
        self.set_formater(dict, self.__class__.format_dict)
        self.set_formater(list, self.__class__.format_list)
        self.set_formater(tuple, self.__class__.format_tuple)

    def set_formater(self, obj, callback):
        self.types[obj] = callback

    def __call__(self, value, **args):
        for key in args:
            setattr(self, key, args[key])
        formater = self.types[type(value) if type(value) in self.types else object]
        return formater(self, value, self.indent)

    def format_object(self, value, indent):
        return repr(value)

    def format_dict(self, value, indent):
        items = [
            self.lfchar + self.htchar * (indent + 1) + repr(key) + ': ' +
            (self.types[type(value[key]) if type(value[key]) in self.types else object])(self, value[key], indent + 1)
            for key in value
        ]
        return '{%s}' % (','.join(items) + self.lfchar + self.htchar * indent)

    def format_list(self, value, indent):
        items = [
            self.lfchar + self.htchar * (indent + 1) + (self.types[type(item) if type(item) in self.types else object])(self, item, indent + 1)
            for item in value
        ]
        return '[%s]' % (','.join(items) + self.lfchar + self.htchar * indent)

    def format_tuple(self, value, indent):
        items = [
            self.lfchar + self.htchar * (indent + 1) + (self.types[type(item) if type(item) in self.types else object])(self, item, indent + 1)
            for item in value
        ]
        return '(%s)' % (','.join(items) + self.lfchar + self.htchar * indent)

इसे आरंभ करने के लिए:

pretty = Formatter()

यह परिभाषित प्रकारों के लिए फॉर्मेटर्स को जोड़ने का समर्थन कर सकता है, आपको बस इसके लिए एक फ़ंक्शन बनाने की आवश्यकता है और इसे उस प्रकार से बाँधें जो आप set_formater के साथ चाहते हैं:

from collections import OrderedDict

def format_ordereddict(self, value, indent):
    items = [
        self.lfchar + self.htchar * (indent + 1) +
        "(" + repr(key) + ', ' + (self.types[
            type(value[key]) if type(value[key]) in self.types else object
        ])(self, value[key], indent + 1) + ")"
        for key in value
    ]
    return 'OrderedDict([%s])' % (','.join(items) +
           self.lfchar + self.htchar * indent)
pretty.set_formater(OrderedDict, format_ordereddict)

ऐतिहासिक कारणों से, मैं पिछले सुंदर प्रिंटर को रखता हूं जो एक वर्ग के बजाय एक फ़ंक्शन था, लेकिन वे दोनों एक ही तरह से उपयोग किए जा सकते हैं, वर्ग संस्करण बस और अधिक अनुमति देते हैं:

def pretty(value, htchar='\t', lfchar='\n', indent=0):
    nlch = lfchar + htchar * (indent + 1)
    if type(value) is dict:
        items = [
            nlch + repr(key) + ': ' + pretty(value[key], htchar, lfchar, indent + 1)
            for key in value
        ]
        return '{%s}' % (','.join(items) + lfchar + htchar * indent)
    elif type(value) is list:
        items = [
            nlch + pretty(item, htchar, lfchar, indent + 1)
            for item in value
        ]
        return '[%s]' % (','.join(items) + lfchar + htchar * indent)
    elif type(value) is tuple:
        items = [
            nlch + pretty(item, htchar, lfchar, indent + 1)
            for item in value
        ]
        return '(%s)' % (','.join(items) + lfchar + htchar * indent)
    else:
        return repr(value)

इसके प्रयेाग के लिए :

>>> a = {'list':['a','b',1,2],'dict':{'a':1,2:'b'},'tuple':('a','b',1,2),'function':pretty,'unicode':u'\xa7',("tuple","key"):"valid"}
>>> a
{'function': <function pretty at 0x7fdf555809b0>, 'tuple': ('a', 'b', 1, 2), 'list': ['a', 'b', 1, 2], 'dict': {'a': 1, 2: 'b'}, 'unicode': u'\xa7', ('tuple', 'key'): 'valid'}
>>> print(pretty(a))
{
    'function': <function pretty at 0x7fdf555809b0>,
    'tuple': (
        'a',
        'b',
        1,
        2
    ),
    'list': [
        'a',
        'b',
        1,
        2
    ],
    'dict': {
        'a': 1,
        2: 'b'
    },
    'unicode': u'\xa7',
    ('tuple', 'key'): 'valid'
}

अन्य संस्करणों की तुलना में:

  • यह समाधान सीधे ऑब्जेक्ट प्रकार के लिए दिखता है, इसलिए आप केवल सूची या तानाशाही ही नहीं, लगभग सब कुछ प्रिंट कर सकते हैं।
  • कोई निर्भरता नहीं है।
  • सब कुछ एक स्ट्रिंग के अंदर रखा जाता है, इसलिए आप इसके साथ जो चाहें कर सकते हैं।
  • कक्षा और समारोह का परीक्षण किया गया है और पायथन 2.7 और 3.4 के साथ काम करता है।
  • आपके अंदर सभी प्रकार की वस्तुएं हो सकती हैं, यह उनका अभ्यावेदन है, न कि उनकी सामग्री जो परिणाम में डाली जा रही है (इसलिए स्ट्रिंग में उद्धरण हैं, यूनिकोड स्ट्रिंग का पूरी तरह से प्रतिनिधित्व है ...)।
  • वर्ग संस्करण के साथ, आप हर इच्छित प्रकार के लिए स्वरूपण जोड़ सकते हैं या पहले से परिभाषित लोगों के लिए उन्हें बदल सकते हैं।
  • कुंजी किसी भी मान्य प्रकार की हो सकती है।
  • इंडेंट और न्यूलाइन चरित्र को हमारे द्वारा पसंद की जाने वाली हर चीज के लिए बदला जा सकता है।
  • डिक्ट, लिस्ट और ट्यूपल्स बहुत प्रिंटेड हैं।

2
यह निश्चित रूप से स्वीकृत समाधान होना चाहिए - JSON पर निर्भरता की कमी बहुत बड़ी है।
जोश

यह अच्छा होगा यदि यह वस्तुओं को डायक्ट्स में परिवर्तित करके और ऑब्जेक्ट प्रकार के लिए उनकी कुंजी सेट करके कर सकता है
एलेक्स कोरी

आप मूल रूप से ऐसा करने के लिए format_object विधि को आंतरिक या बाहरी रूप से बदल सकते हैं।
y.petremann

set_formater - दो टी की जरूरत है, यह एक टाइपो है, फॉर्मेटर होना चाहिए
निकोले प्रोकोपयेव

32

इस तरह से आप इसे बहुत अच्छे तरीके से प्रिंट कर सकते हैं अपने शब्दकोश का नाम यासीन है

import json

print (json.dumps(yasin, indent=2))

5
यह माना जाता है कि डिक्शनरी का कंटेंट json क्रमबद्ध-सक्षम है, जो जरूरी नहीं कि सच हो।
स्पिकेल

8

इसके साथ एक अन्य विकल्प yapf:

from pprint import pformat
from yapf.yapflib.yapf_api import FormatCode

dict_example = {'1': '1', '2': '2', '3': [1, 2, 3, 4, 5], '4': {'1': '1', '2': '2', '3': [1, 2, 3, 4, 5]}}
dict_string = pformat(dict_example)
formatted_code, _ = FormatCode(dict_string)

print(formatted_code)

आउटपुट:

{
    '1': '1',
    '2': '2',
    '3': [1, 2, 3, 4, 5],
    '4': {
        '1': '1',
        '2': '2',
        '3': [1, 2, 3, 4, 5]
    }
}

5

जैसा कि दूसरों ने पोस्ट किया है, आप नेस्टेड डिक्शनरी डेटा को प्रिंट करने के लिए रिकर्सन / डीएफएस का उपयोग कर सकते हैं और अगर यह डिक्शनरी है तो रिकर्सिकली कॉल कर सकते हैं; अन्यथा डेटा प्रिंट करें।

def print_json(data):
    if type(data) == dict:
            for k, v in data.items():
                    print k
                    print_json(v)
    else:
            print data

5

इसके लिए सबसे पाइथोनिक तरीकों में से एक पहले से ही निर्मित पाइप्रिंट मॉड्यूल का उपयोग करना है ।

तर्क जो आपको प्रिंट गहराई को परिभाषित करने के लिए आवश्यक है, जैसा कि आप उम्मीद कर सकते हैं depth

import pprint
pp = pprint.PrettyPrinter(depth=4)
pp.pprint(mydict)

बस !


4

उदाहरण के लिए, आपके द्वारा फेंकी गई कुछ भी चीज़ों को पॉउट प्रिंट कर सकता है ( dataदूसरे उत्तर से उधार लेना ):

data = {'a':2, 'b':{'x':3, 'y':{'t1': 4, 't2':5}}}
pout.vs(data)

आउटपुट को स्क्रीन पर प्रिंट किया जाएगा जैसे:

{
    'a': 2,
    'b':
    {
        'y':
        {
            't2': 5,
            't1': 4
        },
        'x': 3
    }
}

या आप अपनी ऑब्जेक्ट के स्वरूपित स्ट्रिंग आउटपुट को वापस कर सकते हैं:

v = pout.s(data)

इसका प्राथमिक उपयोग मामला डिबगिंग के लिए है, इसलिए यह ऑब्जेक्ट इंस्टेंसेस या किसी भी चीज़ पर चोक नहीं करता है और यह यूनिकोड आउटपुट को संभालता है जैसा कि आप उम्मीद करेंगे, अजगर 2.7 और 3 में काम करता है।

प्रकटीकरण : मैं लेखक और पाउट का अनुचर हूं।


3

मैंने sth का उत्तर लिया और इसे एक नेस्टेड शब्दकोशों और सूचियों की मेरी आवश्यकताओं के अनुसार थोड़ा संशोधित किया:

def pretty(d, indent=0):
    if isinstance(d, dict):
        for key, value in d.iteritems():
            print '\t' * indent + str(key)
            if isinstance(value, dict) or isinstance(value, list):
                pretty(value, indent+1)
            else:
                print '\t' * (indent+1) + str(value)
    elif isinstance(d, list):
        for item in d:
            if isinstance(item, dict) or isinstance(item, list):
                pretty(item, indent+1)
            else:
                print '\t' * (indent+1) + str(item)
    else:
        pass

जो तब मुझे आउटपुट देता है जैसे:

>>> 
xs:schema
    @xmlns:xs
        http://www.w3.org/2001/XMLSchema
    xs:redefine
        @schemaLocation
            base.xsd
        xs:complexType
            @name
                Extension
            xs:complexContent
                xs:restriction
                    @base
                        Extension
                    xs:sequence
                        xs:element
                            @name
                                Policy
                            @minOccurs
                                1
                            xs:complexType
                                xs:sequence
                                    xs:element
                                            ...

1

Sth, मैं सिंक है कि सुंदर है;)

def pretty(d, indent=0):
    for key, value in d.iteritems():
        if isinstance(value, dict):
            print '\t' * indent + (("%30s: {\n") % str(key).upper())
            pretty(value, indent+1)
            print '\t' * indent + ' ' * 32 + ('} # end of %s #\n' % str(key).upper())
        elif isinstance(value, list):
            for val in value:
                print '\t' * indent + (("%30s: [\n") % str(key).upper())
                pretty(val, indent+1)
                print '\t' * indent + ' ' * 32 + ('] # end of %s #\n' % str(key).upper())
        else:
            print '\t' * indent + (("%30s: %s") % (str(key).upper(),str(value)))

1
-1: ऐसे listमूल्यों को नहीं संभालता है जो dictउदाहरण नहीं हैं , pretty({'key': [1, 2, 3]}, indent=4)==> AttributeError: 'int' object has no attribute 'iteritems'। मुझे भी यह कुंजियों को ऊपर उठाने के लिए पसंद नहीं है।
मार्टिअन

आपका समाधान मानता है कि रूट के अंदर एक सूची के अंदर एक तानाशाह नहीं हो सकता। इसके अलावा यह माना जाता है कि हम किसी सूची या टुप्ली को पूर्व-निर्धारित नहीं करना चाहते हैं। अंत में कुंजियों को कैपिटलाइज़ न करें, {'a': 0, 'A': 1} के लिए परिणाम सही नहीं होगा।
y.petremann

1
This class prints out a complex nested dictionary with sub dictionaries and sub lists.  
##
## Recursive class to parse and print complex nested dictionary
##

class NestedDictionary(object):
    def __init__(self,value):
        self.value=value

    def print(self,depth):
        spacer="--------------------"
        if type(self.value)==type(dict()):
            for kk, vv in self.value.items():
                if (type(vv)==type(dict())):
                    print(spacer[:depth],kk)
                    vvv=(NestedDictionary(vv))
                    depth=depth+3
                    vvv.print(depth)
                    depth=depth-3
                else:
                    if (type(vv)==type(list())):
                        for i in vv:
                            vvv=(NestedDictionary(i))
                            depth=depth+3
                            vvv.print(depth)
                            depth=depth-3
                    else:
                        print(spacer[:depth],kk,vv) 

##
## Instatiate and execute - this prints complex nested dictionaries
## with sub dictionaries and sub lists
## 'something' is a complex nested dictionary

MyNest=NestedDictionary(weather_com_result)
MyNest.print(0)

1

मैंने पायथन में एक जोंस ऑब्जेक्ट की सामान्य संरचना को प्रिंट करने के लिए यह सरल कोड लिखा था।

def getstructure(data, tab = 0):
    if type(data) is dict:
        print ' '*tab + '{' 
        for key in data:
            print ' '*tab + '  ' + key + ':'
            getstructure(data[key], tab+4)
        print ' '*tab + '}'         
    elif type(data) is list and len(data) > 0:
        print ' '*tab + '['
        getstructure(data[0], tab+4)
        print ' '*tab + '  ...'
        print ' '*tab + ']'

निम्न डेटा के लिए परिणाम

a = {'list':['a','b',1,2],'dict':{'a':1,2:'b'},'tuple':('a','b',1,2),'function':'p','unicode':u'\xa7',("tuple","key"):"valid"}
getstructure(a)

बहुत कॉम्पैक्ट है और इस तरह दिखता है:

{
  function:
  tuple:
  list:
    [
      ...
    ]
  dict:
    {
      a:
      2:
    }
  unicode:
  ('tuple', 'key'):
}

0

मैं खुद एक रिश्तेदार अजगर नौसिखिया हूं, लेकिन मैं पिछले कुछ हफ्तों से नेस्टेड डिक्शनरी के साथ काम कर रहा हूं और यही मैं साथ आया हूं।

आपको एक स्टैक का उपयोग करने का प्रयास करना चाहिए। किसी सूची की सूची में रूट डिक्शनरी से कुंजियाँ बनाएँ:

stack = [ root.keys() ]     # Result: [ [root keys] ]

पिछले से पहले तक रिवर्स ऑर्डर में जा रहे हैं, शब्दकोश में प्रत्येक कुंजी को देखने के लिए देखें कि क्या इसका मान एक शब्दकोश है। यदि नहीं, तो कुंजी को प्रिंट करें फिर हटाएं। हालांकि अगर कुंजी के लिए मूल्य है डिक्शनरी है, तो कुंजी को प्रिंट करें, फिर स्टैक के अंत में उस मान के लिए कुंजियों को जोड़ दें, और उसी सूची में उसी तरह से प्रोसेसिंग करना शुरू करें, जो कुंजी की प्रत्येक नई सूची के लिए पुनरावृत्ति करता है।

यदि प्रत्येक सूची में दूसरी कुंजी का मान एक शब्दकोश था तो आपके पास कई राउंड के बाद ऐसा कुछ होगा:

[['key 1','key 2'],['key 2.1','key 2.2'],['key 2.2.1','key 2.2.2'],[`etc.`]]

इस दृष्टिकोण के लिए उल्टा यह है कि इंडेंट \tस्टैक की लंबाई से कई गुना अधिक है:

indent = "\t" * len(stack)

नकारात्मक पक्ष यह है कि प्रत्येक कुंजी की जांच करने के लिए आपको संबंधित उप-शब्दकोश के माध्यम से हैश करने की आवश्यकता होती है, हालांकि इसे आसानी से एक सूची समझ और एक सरल forलूप के साथ संभाला जा सकता है :

path = [li[-1] for li in stack]
# The last key of every list of keys in the stack

sub = root
for p in path:
    sub = sub[p]


if type(sub) == dict:
    stack.append(sub.keys()) # And so on

ध्यान रखें कि इस दृष्टिकोण से आपको खाली सूचियों की अनुगामी सफाई करने की आवश्यकता होगी, और किसी भी सूची में अंतिम कुंजी को हटाने के लिए खाली सूची के बाद (जो निश्चित रूप से एक और खाली सूची बना सकते हैं, और इसी तरह)।

इस दृष्टिकोण को लागू करने के अन्य तरीके हैं लेकिन उम्मीद है कि यह आपको यह करने का एक मूल विचार देता है।

संपादित करें: यदि आप उस सब से गुजरना नहीं चाहते हैं, तो pprintमॉड्यूल एक अच्छे प्रारूप में शब्दकोशों को नस्ट करता है।


0

यहाँ मैंने एक फ़ंक्शन लिखा है जो sth की टिप्पणी पर आधारित है। यह इंडेंट के साथ json.dumps के समान काम करता है, लेकिन मैं इंडेंट के लिए जगह के बजाय टैब का उपयोग कर रहा हूं। पायथन 3.2+ में आप इंडेंट को सीधे '\ _' होने के लिए निर्दिष्ट कर सकते हैं, लेकिन 2.7 में नहीं।

def pretty_dict(d):
    def pretty(d, indent):
        for i, (key, value) in enumerate(d.iteritems()):
            if isinstance(value, dict):
                print '{0}"{1}": {{'.format( '\t' * indent, str(key))
                pretty(value, indent+1)
                if i == len(d)-1:
                    print '{0}}}'.format( '\t' * indent)
                else:
                    print '{0}}},'.format( '\t' * indent)
            else:
                if i == len(d)-1:
                    print '{0}"{1}": "{2}"'.format( '\t' * indent, str(key), value)
                else:
                    print '{0}"{1}": "{2}",'.format( '\t' * indent, str(key), value)
    print '{'
    pretty(d,indent=1)
    print '}'

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

>>> dict_var = {'a':2, 'b':{'x':3, 'y':{'t1': 4, 't2':5}}}
>>> pretty_dict(dict_var)
{
    "a": "2",
    "b": {
        "y": {
            "t2": "5",
            "t1": "4"
        },
        "x": "3"
    }
}

मैं इसे अपने समाधान के नेस्टेड तानाशाह के साथ काम नहीं कर सकता, क्योंकि इसने मुझे एक यूनिकोडाइनकोड प्रदान किया है, यह भी आइटम और कुंजियाँ सभी स्ट्रिंग्स में परिवर्तित हो जाती हैं, क्या होगा यदि हम संख्याओं या ट्यूपल्स का उपयोग करते हैं जिसमें सूचियां और डिक्सेस शामिल हैं? Finnaly आपके समाधान को ध्यान में रखते हैं कि हमारी वस्तु जिसे हम सुंदर प्रिंट करना चाहते हैं वह एक तानाशाही होनी चाहिए।
y.petremann

मैं अजगर के लिए एक सामान्य प्रिंट फ़ंक्शन लिखने की कोशिश नहीं कर रहा था। शीर्ष रेटेड टिप्पणियाँ पहले से ही प्रदर्शित करती हैं कि कैसे एक सुंदर प्रिंट करें। मेरा योगदान अजगर 2.7 में टैब के बजाय इंडेंटिंग के लिए json.dumps के साथ एक विकल्प लिखना था।
अल कॉनराड

मैं json.dumps के लिए एक विकल्प लिखने के बारे में आपसे सहमत हूँ, मेरे लिए json.dumps के समान समस्याएं लागू होती हैं। इसके अलावा, आप इंडेंटेशन प्रकार को बदलने के लिए एक साधारण रेगेक्स का उपयोग कर सकते हैं, जिससे आपका कोड सरल हो जाएगा।
y.petremann

0

यहाँ कुछ ऐसा है जो किसी भी प्रकार के नेस्टेड शब्दकोश को प्रिंट करेगा, जबकि रास्ते में "माता-पिता" शब्दकोशों का ट्रैक रखेगा।

dicList = list()

def prettierPrint(dic, dicList):
count = 0
for key, value in dic.iteritems():
    count+=1
    if str(value) == 'OrderedDict()':
        value = None
    if not isinstance(value, dict):
        print str(key) + ": " + str(value)
        print str(key) + ' was found in the following path:',
        print dicList
        print '\n'
    elif isinstance(value, dict):
        dicList.append(key)
        prettierPrint(value, dicList)
    if dicList:
         if count == len(dic):
             dicList.pop()
             count = 0

prettierPrint(dicExample, dicList)

यह विभिन्न प्रारूपों के अनुसार मुद्रण के लिए एक अच्छा प्रारंभिक बिंदु है, जैसे कि ओपी में निर्दिष्ट। आपको बस प्रिंट ब्लॉक के आसपास संचालन करने की आवश्यकता है । ध्यान दें कि यह देखने के लिए लगता है कि मान 'ऑर्डरडीडक्ट ()' है। इस बात पर निर्भर करते हुए कि क्या आप कंटेनर डेटाटिप्स कलेक्शन से कुछ का उपयोग कर रहे हैं , आपको इस प्रकार की विफलता-तिजोरियां बनानी चाहिए, ताकि एलिफ ब्लॉक को इसके नाम के कारण अतिरिक्त शब्दकोश के रूप में न देखें। अब तक, एक उदाहरण शब्दकोश की तरह

example_dict = {'key1': 'value1',
            'key2': 'value2',
            'key3': {'key3a': 'value3a'},
            'key4': {'key4a': {'key4aa': 'value4aa',
                               'key4ab': 'value4ab',
                               'key4ac': 'value4ac'},
                     'key4b': 'value4b'}

छप जाएगा

key3a: value3a
key3a was found in the following path: ['key3']

key2: value2
key2 was found in the following path: []

key1: value1
key1 was found in the following path: []

key4ab: value4ab
key4ab was found in the following path: ['key4', 'key4a']

key4ac: value4ac
key4ac was found in the following path: ['key4', 'key4a']

key4aa: value4aa
key4aa was found in the following path: ['key4', 'key4a']

key4b: value4b
key4b was found in the following path: ['key4']

~ प्रश्न के प्रारूप को फिट करने के लिए कोड बदलना ~

lastDict = list()
dicList = list()
def prettierPrint(dic, dicList):
    global lastDict
    count = 0
    for key, value in dic.iteritems():
        count+=1
        if str(value) == 'OrderedDict()':
            value = None
        if not isinstance(value, dict):
            if lastDict == dicList:
                sameParents = True
            else:
                sameParents = False

            if dicList and sameParents is not True:
                spacing = ' ' * len(str(dicList))
                print dicList
                print spacing,
                print str(value)

            if dicList and sameParents is True:
                print spacing,
                print str(value)
            lastDict = list(dicList)

        elif isinstance(value, dict):
            dicList.append(key)
            prettierPrint(value, dicList)

        if dicList:
             if count == len(dic):
                 dicList.pop()
                 count = 0

समान उदाहरण कोड का उपयोग करते हुए, यह निम्नलिखित प्रिंट करेगा:

['key3']
         value3a
['key4', 'key4a']
                  value4ab
                  value4ac
                  value4aa
['key4']
         value4b

यह वही नहीं है जो ओपी में अनुरोध किया गया है। अंतर यह है कि एक अभिभावक ^ n अनुपस्थित होने के बजाय अभी भी छपा हुआ है और इसे सफेद-स्थान के साथ बदल दिया गया है। ओपी के प्रारूप को प्राप्त करने के लिए, आपको निम्नलिखित की तरह कुछ करने की आवश्यकता होगी: पुनरावृत्त इसकी तुलना अंतिम प्रश्न के साथ dicList से करें । आप पता चल सके कि एक नया शब्दकोश बनाने और इसे करने के लिए dicList की सामग्री को कॉपी करके ऐसा कर सकते हैं, मैं कॉपी किया शब्दकोश में रूप में ही है मैं lastDict में, और - अगर यह है - कि करने के लिए खाली स्थान के लेखन मैं स्ट्रिंग गुणक फ़ंक्शन का उपयोग कर स्थिति ।


0

से इस लिंक :

def prnDict(aDict, br='\n', html=0,
            keyAlign='l',   sortKey=0,
            keyPrefix='',   keySuffix='',
            valuePrefix='', valueSuffix='',
            leftMargin=0,   indent=1 ):
    '''
return a string representive of aDict in the following format:
    {
     key1: value1,
     key2: value2,
     ...
     }

Spaces will be added to the keys to make them have same width.

sortKey: set to 1 if want keys sorted;
keyAlign: either 'l' or 'r', for left, right align, respectively.
keyPrefix, keySuffix, valuePrefix, valueSuffix: The prefix and
   suffix to wrap the keys or values. Good for formatting them
   for html document(for example, keyPrefix='<b>', keySuffix='</b>'). 
   Note: The keys will be padded with spaces to have them
         equally-wide. The pre- and suffix will be added OUTSIDE
         the entire width.
html: if set to 1, all spaces will be replaced with '&nbsp;', and
      the entire output will be wrapped with '<code>' and '</code>'.
br: determine the carriage return. If html, it is suggested to set
    br to '<br>'. If you want the html source code eazy to read,
    set br to '<br>\n'

version: 04b52
author : Runsun Pan
require: odict() # an ordered dict, if you want the keys sorted.
         Dave Benjamin 
         http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/161403
    '''

    if aDict:

        #------------------------------ sort key
        if sortKey:
            dic = aDict.copy()
            keys = dic.keys()
            keys.sort()
            aDict = odict()
            for k in keys:
                aDict[k] = dic[k]

        #------------------- wrap keys with ' ' (quotes) if str
        tmp = ['{']
        ks = [type(x)==str and "'%s'"%x or x for x in aDict.keys()]

        #------------------- wrap values with ' ' (quotes) if str
        vs = [type(x)==str and "'%s'"%x or x for x in aDict.values()] 

        maxKeyLen = max([len(str(x)) for x in ks])

        for i in range(len(ks)):

            #-------------------------- Adjust key width
            k = {1            : str(ks[i]).ljust(maxKeyLen),
                 keyAlign=='r': str(ks[i]).rjust(maxKeyLen) }[1]

            v = vs[i]        
            tmp.append(' '* indent+ '%s%s%s:%s%s%s,' %(
                        keyPrefix, k, keySuffix,
                        valuePrefix,v,valueSuffix))

        tmp[-1] = tmp[-1][:-1] # remove the ',' in the last item
        tmp.append('}')

        if leftMargin:
          tmp = [ ' '*leftMargin + x for x in tmp ]

        if html:
            return '<code>%s</code>' %br.join(tmp).replace(' ','&nbsp;')
        else:
            return br.join(tmp)     
    else:
        return '{}'

'''
Example:

>>> a={'C': 2, 'B': 1, 'E': 4, (3, 5): 0}

>>> print prnDict(a)
{
 'C'   :2,
 'B'   :1,
 'E'   :4,
 (3, 5):0
}

>>> print prnDict(a, sortKey=1)
{
 'B'   :1,
 'C'   :2,
 'E'   :4,
 (3, 5):0
}

>>> print prnDict(a, keyPrefix="<b>", keySuffix="</b>")
{
 <b>'C'   </b>:2,
 <b>'B'   </b>:1,
 <b>'E'   </b>:4,
 <b>(3, 5)</b>:0
}

>>> print prnDict(a, html=1)
<code>{
&nbsp;'C'&nbsp;&nbsp;&nbsp;:2,
&nbsp;'B'&nbsp;&nbsp;&nbsp;:1,
&nbsp;'E'&nbsp;&nbsp;&nbsp;:4,
&nbsp;(3,&nbsp;5):0
}</code>

>>> b={'car': [6, 6, 12], 'about': [15, 9, 6], 'bookKeeper': [9, 9, 15]}

>>> print prnDict(b, sortKey=1)
{
 'about'     :[15, 9, 6],
 'bookKeeper':[9, 9, 15],
 'car'       :[6, 6, 12]
}

>>> print prnDict(b, keyAlign="r")
{
        'car':[6, 6, 12],
      'about':[15, 9, 6],
 'bookKeeper':[9, 9, 15]
}
'''

0

मैं तो बस लेने के बाद यह सवाल करने के लिए लौट रहा हूँ sth के जवाब और एक छोटी लेकिन बहुत उपयोगी संशोधन करने। यह फ़ंक्शन JSON ट्री के साथ-साथ उस ट्री में लीफ नोड्स के आकार की सभी कुंजियों को प्रिंट करता है ।

def print_JSON_tree(d, indent=0):
    for key, value in d.iteritems():
        print '    ' * indent + unicode(key),
        if isinstance(value, dict):
            print; print_JSON_tree(value, indent+1)
        else:
            print ":", str(type(d[key])).split("'")[1], "-", str(len(unicode(d[key])))

यह वास्तव में अच्छा है जब आपके पास बड़ी JSON ऑब्जेक्ट्स हैं और यह पता लगाना चाहते हैं कि मांस कहाँ है। उदाहरण :

>>> print_JSON_tree(JSON_object)
key1
    value1 : int - 5
    value2 : str - 16
    key2
       value1 : str - 34
       value2 : list - 5623456

यह आपको बताएगा कि आपके द्वारा परवाह किए जाने वाले अधिकांश डेटा संभवतः अंदर हैं JSON_object['key1']['key2']['value2']क्योंकि स्ट्रिंग के रूप में स्वरूपित उस मान की लंबाई बहुत बड़ी है।


0

इस फ़ंक्शन का उपयोग करें:

def pretty_dict(d, n=1):
    for k in d:
        print(" "*n + k)
        try:
            pretty_dict(d[k], n=n+4)
        except TypeError:
            continue

इसे इस तरह से कॉल करें:

pretty_dict(mydict)

यदि मान तार हैं, तो यह काम नहीं करता है। यह स्ट्रिंग के प्रत्येक चरित्र को एक नई लाइन पर प्रिंट करता है, लेकिन चाबियाँ ठीक काम करती हैं।
एंथनी

0

यह वह है जो मैं एक .txt फ़ाइल में एक शब्दकोश लिखने के लिए आवश्यक एक वर्ग पर काम करते समय आया था।

@staticmethod
def _pretty_write_dict(dictionary):

    def _nested(obj, level=1):
        indentation_values = "\t" * level
        indentation_braces = "\t" * (level - 1)
        if isinstance(obj, dict):
            return "{\n%(body)s%(indent_braces)s}" % {
                "body": "".join("%(indent_values)s\'%(key)s\': %(value)s,\n" % {
                    "key": str(key),
                    "value": _nested(value, level + 1),
                    "indent_values": indentation_values
                } for key, value in obj.items()),
                "indent_braces": indentation_braces
            }
        if isinstance(obj, list):
            return "[\n%(body)s\n%(indent_braces)s]" % {
                "body": "".join("%(indent_values)s%(value)s,\n" % {
                    "value": _nested(value, level + 1),
                    "indent_values": indentation_values
                } for value in obj),
                "indent_braces": indentation_braces
            }
        else:
            return "\'%(value)s\'" % {"value": str(obj)}

    dict_text = _nested(dictionary)
    return dict_text

अब, अगर हमारे पास इस तरह का एक शब्दकोष है:

some_dict = {'default': {'ENGINE': [1, 2, 3, {'some_key': {'some_other_key': 'some_value'}}], 'NAME': 'some_db_name', 'PORT': '', 'HOST': 'localhost', 'USER': 'some_user_name', 'PASSWORD': 'some_password', 'OPTIONS': {'init_command': 'SET foreign_key_checks = 0;'}}}

और हम करते हैं:

print(_pretty_write_dict(some_dict))

हमें मिला:

{
    'default': {
        'ENGINE': [
            '1',
            '2',
            '3',
            {
                'some_key': {
                    'some_other_key': 'some_value',
                },
            },
        ],
        'NAME': 'some_db_name',
        'OPTIONS': {
            'init_command': 'SET foreign_key_checks = 0;',
        },
        'HOST': 'localhost',
        'USER': 'some_user_name',
        'PASSWORD': 'some_password',
        'PORT': '',
    },
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.