İç içe sözlükler nasıl yazdırılır?


289

Python'da ~ 4 derinliğe sahip bir sözlüğü nasıl yazdırabilirim? İle güzel baskı denedim pprint(), ama işe yaramadı:

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

Sadece "\t"her yuvalama için bir girinti ( ) istiyorum , böylece böyle bir şey olsun:

key1
    value1
    value2
    key2
       value1
       value2

vb.

Bunu nasıl yapabilirim?


29
"İşe yaramadı" ne anlama geliyor? Lütfen pprint "çalışmayan" tam olarak belirtin.
S.Lott

5
Şimdi bu cevapların 3'ünü kullandım (belirli bir senaryoda her iyi): @ Ken'in json cevabı iyidir ama nesne json serileştirilemediğinde bazen başarısız olur (istisna atar). @ Ken'in json cevabı işe yaramazsa @ Andy'nin yaml cevabını deneyin ve işe yaramalı , ancak dize çıktısı biraz daha az insan tarafından okunabilir. [@ sth'nin cevabı] en genel olanıdır (herhangi bir nesne için çalışmalı ve herhangi bir kütüphaneyi kullanmamalıdır).
Trevor Boyd Smith

Yanıtlar:


143

Biçimlendirmenin tam olarak nasıl görünmesini istediğinizden emin değilim, ancak böyle bir işlevle başlayabilirsiniz:

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
@ Ken'in geleneksel cevabının bundan çok daha iyi olduğunu biliyorum. Json zaten her şeyi yönetir ve bu hataları verebilir böyle: UnicodeEncodeError: 'ASCII' codec'i olamaz kodlamak karakter u '\ XF3' pozisyonunda 50'de: Sıralı olmayan aralığında (128)
WonderWhy

Çözümümün iç içe dikimi ile çalışmasını sağlayamıyorum, çünkü bana bir UnicodeEncodeError verdi, ayrıca dict anahtarı yazdırmıyor, liste ve tuples içine girmeyin ve bir python geçerli sözdizimi tutmayın.
y.petremann

Bu cevap benim için bir cazibe gibi çalıştı, ancak yeni bir soru yayınladım stackoverflow.com/questions/36972225/… .
gsamaras

Oldukça iyi. OP'nin sorusundaki gibi iç içe listeleriniz varsa, bunun için biraz işlem eklemeniz gerekir. Py2'de sorun yaşıyorsanız, bunun __future__cevabından bahsettiği gibi kesmek olmadan Unicode'u düzgün bir şekilde işleyememesi , bu nedenle gerektiğinde bunları kullanmanız gerekir (veya zaten 3'e güncelleyin).
sudo

Bu benim için yeterince iyi çalıştı: 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

İlk düşüncem JSON serileştiricisinin iç içe sözlüklerde muhtemelen oldukça iyi olmasıydı, bu yüzden hile yapıp şunu kullanırım:

>>> 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
Bu harika, ancak tüm sözlükleri iyi yazdırmıyor. print json.dumps (myObject .__ dict__, sort_keys = Doğru, girinti = 4) #TypeError: <0x0000000002E6A748'deki nesne JSON serileştirilemez
tponthieux 8:30 '

4
Bu yararlı görünse de, çıktı OP'nin istediği şey değil.
martineau

2
@martineau: OP'nin istenen çıktısı mantıklı değil, sözlüklerin değer başına anahtarlara ihtiyacı var.
naught101

2
@ naught101: Güzel bir yazıcı istenen çıktıyı üretmek için ne gerekiyorsa yapabilir.
martineau

22
json.dumps isteğe bağlı bir argüman olarak bir dönüştürme işlevi alır, bu nedenle json.dumps (myObject .__ dict__, sort_keys = True, indent = 4, deault = str) ile en azından kendisini yazdırmak ve yuvarlak almak için repr nesnelerini kullanabilirsiniz 'JSON serileştirilemez' TypeError
RFairey

56

Sen deneyebilirsiniz YAML aracılığıyla PyYAML . Çıkışı ince ayar yapılabilir. Aşağıdakilerden başlamayı öneririm:

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

Sonuç çok okunabilir; gerektiğinde Python'a da ayrıştırılabilir.

Düzenle:

Misal:

>>> 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
Veri türünü biçiminin üzerinde tuttuğu için yaml kullanmak çok ilginç, buna karşı söyleyebileceğim tek şey, geçerli bir python dizesi üretmemesi, ancak neredeyse python'a dönüştürülebilmesidir.
y.petremann

1
yaml Numpy'nin skaler tip versiyonunu sevmiyor ... Numpy dizileri desteklemediğine şaşırmadım, ama a floatve a için aynı çıkışı numpy.float64
beklerdim

Bu yaklaşım benim için de bir sözlük listesi kullanarak işe yaradı
Grant Shannon

36

Ne yapıldığından itibaren, en azından python yorumlayıcısının çıktısını taklit eden çok basit bir biçimlendirme ile güzel bir yazıcı görmüyorum, böylece benim:

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)

Başlamak için:

pretty = Formatter()

Tanımlanmış türler için biçimlendiricilerin eklenmesini destekleyebilir, bunun için böyle bir işlev yapmanız ve set_formater ile istediğiniz türe bağlamanız yeterlidir:

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)

Tarihsel nedenlerden ötürü, bir sınıf yerine bir işlev olan önceki güzel yazıcıyı saklıyorum, ancak her ikisi de aynı şekilde kullanılabilir, sınıf sürümü sadece çok daha fazlasına izin verir:

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)

Kullanmak için:

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

Diğer sürümlerle karşılaştırıldığında:

  • Bu çözüm doğrudan nesne türünü arar, böylece sadece liste veya dikte değil, hemen hemen her şeyi yazdırabilirsiniz.
  • Hiç bağımlılığı yok.
  • Her şey bir dizenin içine konur, böylece onunla ne istersen yapabilirsin.
  • Sınıf ve işlev test edilmiştir ve Python 2.7 ve 3.4 ile çalışır.
  • İçinde her türlü nesneye sahip olabilirsiniz, bu onların temsilidir ve sonuca konan içerikleri değildir (dize tırnak işaretleri içerir, Unicode dize tamamen temsil edilir ...).
  • Sınıf sürümü ile, istediğiniz her nesne türü için biçimlendirme ekleyebilir veya bunları önceden tanımlanmış olanlar için değiştirebilirsiniz.
  • anahtarı geçerli herhangi bir türde olabilir.
  • Girinti ve Newline karakteri istediğimiz her şey için değiştirilebilir.
  • Diksiyon, Liste ve Tuples oldukça basılır.

2
Bu kesinlikle kabul edilen çözüm olmalıdır - JSON'a bağımlılığın olmaması çok büyük.
Josh

nesneleri diktüre dönüştürerek ve anahtarlarını nesne türü olarak ayarlayarak yapabilirse
Alex Cory

Bunu yapmak için temel olarak format_object yöntemini dahili veya harici olarak değiştirebilirsiniz.
y.petremann

set_formater - iki t gerekir, bu bir yazım hatası, biçimlendirici olmalıdır
Nikolay Prokopyev

32

bu şekilde güzel bir şekilde yazdırabilirsiniz, örneğin sözlük adınız yasin

import json

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

5
Bu, sözlüğün içeriğinin json serileştirilebildiğini varsayar ve bu mutlaka doğru değildir.
SpiXel

8

Şununla başka bir seçenek 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)

Çıktı:

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

5

Diğerlerinin yayınladığı gibi, iç içe sözlük verilerini yazdırmak için özyineleme / dfs kullanabilir ve sözlükse özyinelemeli olarak çağırabilirsiniz; aksi takdirde verileri yazdırın.

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

5

Bunun için en pythonic yollarından biri zaten inşa pprint modülünü kullanmaktır.

Baskı derinliğini tanımlamak için ihtiyacınız olan argüman beklediğiniz gibi depth

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

Bu kadar !


4

pout , attığınız her şeyi güzel bir şekilde basabilir, örneğin ( databaşka bir cevaptan ödünç almak):

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

çıktı çıktısı aşağıdaki gibi ekrana yazdırılır:

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

veya nesnenizin biçimlendirilmiş dize çıktısını döndürebilirsiniz:

v = pout.s(data)

Birincil kullanım durumu hata ayıklama içindir, bu nedenle nesne örneklerini veya herhangi bir şeyi boğmaz ve unicode çıktısını beklediğiniz gibi işler, python 2.7 ve 3'te çalışır.

ifşa : Ben pout'un yazarı ve koruyucusuyum.


3

Çektiğim STH yanıtını ve iç içe geçmiş sözlükler ve listelerin benim ihtiyaçlarına uygun hafifçe değiştirilmiş:

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

Sonra bana şöyle çıktı verir:

>>> 
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, bu güzel batıyorum;)

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: Örnek listolmayan değerleri işlemez dict, yani pretty({'key': [1, 2, 3]}, indent=4)==> AttributeError: 'int' object has no attribute 'iteritems'. Ben de büyük tuşları sevmiyorum.
martineau

Çözümünüz, kök diksiyon içindeki bir liste içinde bir diksiyon olamayacağını düşünüyor. Ayrıca, bir listeyi ya da bir parçayı yeniden yazdırmak istemediğimizi düşünüyoruz. Son olarak anahtarları büyük harfle yazmayın, {'a': 0, 'A': 1} için sonuç doğru olmaz.
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

Python'da bir json nesnesinin genel yapısını yazdırmak için bu basit kodu yazdım.

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şağıdaki veriler için sonuç

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)

çok kompakttır ve şöyle görünür:

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

0

Ben kendimi göreceli bir python acemi değilim ama son birkaç haftadır iç içe sözlüklerle çalışıyorum ve ben de bunu başardım.

Bir yığın kullanmayı denemelisiniz. Kök sözlüğündeki anahtarları bir liste listesine dönüştürün:

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

Sondan ilkeye doğru sırayla ilerleyerek, değerinin bir sözlük olup olmadığını görmek için sözlükteki her anahtarı arayın. Değilse, anahtarı yazdırın ve silin. Ancak, anahtarın değeri bir sözlükse, anahtarı yazdırın ve o değerin anahtarlarını yığının sonuna ekleyin ve her yeni anahtar listesi için yinelemeli olarak yinelenerek bu listeyi işlemeye başlayın.

Her listedeki ikinci anahtarın değeri bir sözlük olsaydı, birkaç turdan sonra böyle bir şey olurdu:

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

Bu yaklaşımın tersi, girintinin \tyığının uzunluğunun sadece iki katı olmasıdır:

indent = "\t" * len(stack)

Dezavantajı, her bir anahtarı kontrol etmek için ilgili alt sözlüğe hash yapmanız gerektiğidir, ancak bu bir liste kavrama ve basit bir fordöngü ile kolayca ele alınabilir :

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

Bu yaklaşımın sondaki boş listeleri temizlemenizi gerektireceğini ve boş bir listenin (elbette başka bir boş liste oluşturabileceği vb.) Herhangi bir listedeki son anahtarı silmenizi .

Bu yaklaşımı uygulamanın başka yolları da vardır ama umarım bu nasıl yapılacağına dair temel bir fikir verir.

DÜZENLEME: Tüm bunları yapmak istemiyorsanız, pprintmodül iç içe sözlükleri güzel bir biçimde yazdırır.


0

İşte sth'nin yorumuna dayanarak yazdığım bir fonksiyon. Girintili json.dumps ile aynı şekilde çalışır, ancak girintiler için boşluk yerine sekmeler kullanıyorum. Python 3.2 ve üzeri sürümlerde girintiyi doğrudan bir '\ t' olarak belirtebilirsiniz, ancak 2.7'de değil.

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

Ör:

>>> 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"
    }
}

Bana bir UnicodeEncodeError verdi, çünkü benim çözüm iç içe dikti ile çalışmasını sağlayamıyorum, ayrıca öğeleri ve anahtarları tüm dizeleri dönüştürülür, ne sayıları veya tuples içeren listeleri ve dikimleri kullanırsanız? Neyse ki çözümünüz, güzel yazdırmak istediğimiz nesnemizin bir diksiyon olması gerektiğini göz önünde bulundurur.
y.petremann

Bir python dict için genel bir yazdırma işlevi yazmaya çalışmıyordum. En çok oy alan yorumlar zaten bir diktenin nasıl yazdırılacağını gösteriyor. Benim katkım psonhon 2.7 sekmeler yerine girinti için '\ t' ile json.dumps alternatif yazmak oldu.
Al Conrad

Sizin için json.dumps'a alternatif yazma konusunda katılıyorum, benim için json.dumps ile aynı sorunlar geçerlidir. Ayrıca, girintileme türünü değiştirmek için basit bir normal ifade kullanarak kodunuzu daha basit hale getirebilirsiniz.
y.petremann

0

İşte yol boyunca "üst" sözlükleri takip ederken, her türlü iç içe sözlük yazdıracak bir şey.

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)

Bu, OP'de belirtilen gibi farklı biçimlere göre yazdırmak için iyi bir başlangıç ​​noktasıdır . Gerçekten yapmanız gereken, Baskı bloklarının etrafındaki işlemler . Değerin 'OrderedDict ()' olup olmadığını göründüğünü unutmayın. Container veri türü Koleksiyonlarından bir şey kullanıp kullanmadığınıza bağlı olarak , elif bloğunun adı nedeniyle ek bir sözlük olarak görmemesi için bu tür başarısız kasalar yapmalısınız. Şimdilik örnek bir sözlük

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

yazdıracak

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

~ sorunun biçimine uyacak şekilde kodu değiştirmek ~

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

Aynı örnek kodu kullanarak aşağıdakileri yazdıracaktır:

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

Bu değil tam OP isteneni. Aradaki fark, bir üst ^ n'nin bulunmaması ve boşlukla değiştirilmesi yerine hala yazdırılmasıdır. OP'ın biçimine almak için aşağıdaki gibi bir şey yapmak gerekir: iteratif karşılaştırmak dicList ile lastDict . Sen eğer kontrol Yeni sözlük yapma ve ona dicList içeriğini kopyalayarak yapabilirsiniz i kopyalanan sözlükte aynıdır i lastDict içinde ve - bu ise - buna boşluk yazma i dize çarpan işlevini kullanarak pozisyon .


0

Gönderen bu bağlantı :

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

Sadece aldıktan sonra bu soruya iade ediyorum sth cevabını ve küçük ama çok kullanışlı değişiklik yapma. Bu işlev , JSON ağacındaki tüm anahtarların yanı sıra o ağaçtaki yaprak düğümlerinin boyutunu yazdırır .

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])))

Büyük JSON nesneleriniz olduğunda ve etin nerede olduğunu bulmak istediğinizde gerçekten güzel. Örnek :

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

Bu, önem verdiğiniz verilerin çoğunun muhtemelen içeride JSON_object['key1']['key2']['value2']olduğunu söyler çünkü bir dize olarak biçimlendirilmiş bu değerin uzunluğu çok büyüktür.


0

Bu işlevi kullanın:

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

Buna şöyle deyin:

pretty_dict(mydict)

Değerler dizeyse bu çalışmaz. Dizenin her karakterini yeni bir satıra yazdırır, ancak tuşlar düzgün çalışıyor gibi görünür.
Anthony

0

Bu, bir .txt dosyasına sözlük yazmak için gereken bir sınıf üzerinde çalışırken geldi:

@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

Şimdi, böyle bir sözlüğümüz varsa:

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

Ve yapıyoruz:

print(_pretty_write_dict(some_dict))

Biz:

{
    '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': '',
    },
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.