중첩 된 사전을 예쁘게 인쇄하는 방법은 무엇입니까?


289

파이썬에서 깊이가 ~ 4 인 사전을 어떻게 인쇄합니까? 로 예쁜 인쇄를 시도했지만 pprint()작동하지 않았습니다.

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

"\t"각 중첩마다 들여 쓰기 ( )를 원하므로 다음과 같이 얻을 수 있습니다.

key1
    value1
    value2
    key2
       value1
       value2

기타

어떻게해야합니까?


29
"작동하지 않았다"는 무슨 뜻입니까? pprint가 "작동하지 않는"방법을 매우 정확하게 지정하십시오.
S.Lott

5
지금이 답변 3 (특정 시나리오에서 각각 좋은) 사용하고 있습니다 : 켄의 JSON 응답이 @ 좋지만 오브젝트가 JSON 직렬화 (예외를 throw) 할 수없는 경우에 때때로 실패합니다. @Ken의 json 답변이 작동하지 않으면 @Andy의 yaml 답변을 시도 하고 작동해야하지만 문자열 출력은 사람이 읽을 수 없습니다. [@ sth 's answer]가 가장 일반적입니다 (모든 객체에서 작동해야하며 라이브러리를 사용하지 않아야 함).
Trevor Boyd Smith

답변:


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
@Ken의 기존 답변이 이것보다 훨씬 낫다는 것을 알고 있습니다. JSON은 이미 모든 것을 처리하고이 오류를 줄 수있는 등 : UnicodeEncodeError : '아스키'코덱 수 없습니다 인코딩 문자 U '\ xf3'위치 (50) : 순서없는 범위 (128)
wonderwhy

유니 코드 EncodeError가 발생했기 때문에 내 솔루션의 중첩 된 dict와 함께 작동하도록 할 수 없으며 dict 키를 인쇄하지 않으며 목록과 튜플에 들어 가지 않고 파이썬 유효한 구문을 유지하지 않습니다.
y.petremann

이 답변은 저에게 매력처럼 작용했지만 인쇄 할 값의 수를 제한 하는 새로운 질문 stackoverflow.com/questions/36972225/… 를 게시했습니다 .
gsamaras

꽤 좋아요 OP의 질문과 같이 중첩 된 목록이있는 경우 처리 목록을 추가해야합니다. Py2에 문제가있는 __future__경우 답변에서 언급 한 것처럼 해킹없이 유니 코드를 올바르게 처리 할 수 ​​없으므로 필요에 따라 (또는 이미 3으로 업데이트) 사용해야합니다.
sudo

이것은 나를 위해 충분히 일했다 : 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
이것은 멋지지만 모든 사전을 잘 인쇄하지는 않습니다. print json.dumps (myObject .__ dict__, sort_keys = True, indent = 4) #TypeError : <0x0000000002E6A748의 객체는 JSON 직렬화 가능하지 않습니다
tponthieux

4
이것이 유용 해 보이지만 결과는 OP가 원하는 것이 아닙니다.
martineau

2
@martineau : OP의 요청 된 출력이 의미가 없으므로 사전에는 값당 키가 필요합니다.
naught101

2
@ naught101 : 예쁜 프린터는 원하는 출력을 만드는 데 필요한 모든 것을 할 수 있습니다.
martineau

22
json.dumps는 변환 함수를 선택적 인수로 사용하므로 json.dumps (myObject .__ dict__, sort_keys = True, indent = 4, deault = str)를 사용하면 최소한 repr 의 객체 구현을 사용할 수 있습니다 하여 인쇄하고 반올림 할 수 있습니다. '하지 JSON 직렬화'형식 오류
RFairey

56

PyYAML을 통해 YAML 을 시도 할 수 있습니다. 출력을 미세 조정할 수 있습니다. 다음으로 시작하는 것이 좋습니다.

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
yaml을 사용하는 것은 데이터 형식을 형식보다 유지하기 때문에 매우 흥미 롭습니다. 내가 말할 수있는 유일한 것은 유효한 파이썬 문자열을 생성하지 않지만 거의 파이썬으로 다시 변환 할 수 있다는 것입니다.
y.petremann

1
YAML 내가 NumPy와 배열을 지원하지 않습니다입니다 놀라지 않았다 ... 스칼라 유형의 NumPy와의 버전처럼하지 않습니다,하지만 난에 대해 동일한 출력 예상 한 것 floatnumpy.float64
PhilMacKay

이 방법은 또한 사전 목록을 사용하여 저에게
Grant Shannon

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

다른 버전과 비교 :

  • 이 솔루션은 객체 유형을 직접 검색하므로 목록이나 받아쓰기뿐만 아니라 거의 모든 것을 인쇄 할 수 있습니다.
  • 의존성이 없습니다.
  • 모든 것이 문자열 안에 들어가므로 원하는대로 무엇이든 할 수 있습니다.
  • 클래스와 함수는 테스트되었으며 Python 2.7 및 3.4에서 작동합니다.
  • 모든 유형의 객체를 내부에 가질 수 있습니다. 결과에 넣는 내용이 아니라 표현입니다 (문자열에는 따옴표가 있고 유니 코드 문자열은 완전히 표시됩니다 ...).
  • 클래스 버전을 사용하면 원하는 모든 객체 유형에 대한 서식을 추가하거나 이미 정의 된 객체 유형에 대해 형식을 변경할 수 있습니다.
  • key는 유효한 유형일 수 있습니다.
  • 들여 쓰기 및 줄 바꿈 문자는 원하는 모든 항목으로 변경할 수 있습니다.
  • Dict, List 및 Tuples는 꽤 인쇄됩니다.

2
이것은 분명히 수용 가능한 솔루션이어야합니다 .JSON에 대한 종속성이 부족합니다.
Josh

객체를 dicts로 변환하고 키를 객체 유형으로 설정하여 객체를 수행 할 수 있다면 멋질 것입니다.
Alex Cory

기본적으로 format_object 메소드를 internaly 또는 externaly로 바꾸면됩니다.
y.petremann

set_formater - 필요 이톤,이 오타입니다, 포맷해야
니콜라이 Prokopyev

32

이 방법으로 당신은 예를 들어 사전 이름이 yasin 예쁘게 인쇄 할 수 있습니다

import json

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

5
이것은 사전의 내용이 json 직렬화 가능하다고 가정하며, 반드시 그렇지는 않습니다.
SpiXel

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

다른 사람들이 게시 한 것처럼 recursion / dfs를 사용하여 중첩 된 사전 데이터를 인쇄하고 사전 인 경우 재귀 적으로 호출 할 수 있습니다. 그렇지 않으면 데이터를 인쇄하십시오.

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

5

이를위한 가장 비법적인 방법 중 하나는 이미 빌드 된 pprint 를 사용하는 것입니다 모듈 입니다.

인쇄 깊이를 정의하는 데 필요한 인수는 예상대로입니다 depth

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

그게 다야!


4

pout 은 예를 들어 ( 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에서 작동합니다.

공개 : 저는 pout의 저자이자 관리자입니다.


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'. 나는 또한 대문자 키를 좋아하지 않습니다.
martineau

귀하의 솔루션은 루트 dict 내부의 목록 안에 dict가있을 수 없다고 생각합니다. 또한 목록이나 튜플을 예쁘게 인쇄하고 싶지 않다고 생각합니다. 마지막으로 키를 대문자로 쓰지 마십시오. { '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

이 간단한 코드를 작성하여 Python에서 json 객체의 일반적인 구조를 인쇄했습니다.

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와 동일하게 작동하지만 들여 쓰기 공간 대신 ​​탭을 사용하고 있습니다. Python 3.2 이상에서는 들여 쓰기를 '\ t'로 지정할 수 있지만 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"
    }
}

유니 코드 EncodeError를 제공했기 때문에 내 솔루션의 중첩 된 dict와 함께 작동시킬 수 없습니다. 항목과 키가 모두 문자열로 변환됩니다. 목록과 dicts가 포함 된 숫자 또는 튜플을 사용하면 어떻게됩니까? Finnaly 솔루션은 우리가 예쁘게 인쇄하고자하는 객체가 dict이어야한다는 것을 고려합니다.
y.petremann

파이썬 dict에 대한 일반적인 인쇄 함수를 쓰려고하지 않았습니다. 최고 등급의 의견은 이미 dict을 예쁘게 인쇄하는 방법을 보여줍니다. 내 기여는 파이썬 2.7의 탭 대신 들여 쓰기를 위해 '\ t'로 json.dumps에 대한 대안을 작성하는 것이 었습니다.
Al Conrad

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)

이것은 OP에 지정된 것과 같은 다른 형식에 따라 인쇄하기에 좋은 출발점 입니다. 인쇄 블록 주변의 작업 만하면됩니다. 값이 'OrderedDict ()'인지 확인합니다. Container datatypes Collections 에서 무언가를 사용하고 있는지에 따라 elif 블록이 이름으로 인해 추가 사전으로 표시되지 않도록 이러한 종류의 페일 세이프를 만들어야합니다 . 현재로서는 사전 예를 들어

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

이것은 아닙니다 정확히 OP에 요청 것을. 차이점은 부모가없는 경우 공백으로 대체되지 않고 여전히 인쇄됩니다. OP의 형식에 도착하려면 다음과 같은 작업을 수행해야합니다 : 반복적으로 비교 dicList을lastDict . 다음과 같은 경우 점검, 새 사전을 만들고 그것에 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)

값이 문자열이면 작동하지 않습니다. 문자열의 각 문자를 새 줄에 인쇄하지만 키는 정상적으로 작동합니다.
Anthony

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': '',
    },
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.