如何打印包含多个列表和字典的嵌套词典?

时间:2020-05-15 09:39:33

标签: python list dictionary

[[{'text': '\n     ', 'category': 'cooking', 'title': {'text': 'Everyday 
  Italian', 'lang': 'en'}, 'author': {'text': 'Giada De Laurentiis'}, 'year': 
  {'text': '2005'}, 'price': {'text': '30.00'}}, 
  {'text': '\n     ', 'category': 'children', 'title': {'text': 'Harry Potter', 
  'lang': 'en'}, 'author': {'text': 'J K. Rowling'}, 'year': {'text': 
  '2005'}, 'price': {'text': '29.99'}}, {'text': '\n     ', 'category': 
  'web', 'title': {'text': 'XQuery Kick Start', 'lang': 'en'}, 'author': 
  [{'text': 'James McGovern'}, {'text': 'Per Bothner'}, {'text': 'Kurt 
  Cagle'}, {'text': 'James Linn'}, {'text': 'Vaidyanathan Nagarajan'}], 
  'year': {'text': '2003'}, 'price': {'text': '49.99'}}, {'text': '\n     ', 
  'category': 'web', 'cover': 'paperback', 'title': {'text': 'Learning XML', 
  'lang': 'en'}, 'author': {'text': 'Erik T. Ray'}, 'year': {'text': '2003'}, 
  'price': {'text': '39.95'}}]]

输出格式:

category : cooking,
title : ['Everyday Italian', 'lang': 'en'],
author : Giada De Laurentiis,
year : '2005',
price : '30.00'

category : children,
title : ['Harry Potter', 'lang': 'en'],
author : 'J K. Rowling',
year : '2005',
price : '29.99'

category : web,
title : [ 'XQuery Kick Start''lang': 'en'],
author :[ 'James McGovern' , 'Per Bothner','Kurt Cagle','James Linn', 'Vaidyanathan Nagarajan'],
year :  '2003',
price :  '49.99'

category : web,
cover : paperback,
title : [ 'Learning XML','lang': 'en'],
author : 'Erik T. Ray',
year :  '2003',
price : '39.95'

4 个答案:

答案 0 :(得分:1)

像下面这样的简单循环应该获得所需的输出。

for entry in data[0]:
    for k, v in entry.items():
        print(k, ':', v)

答案 1 :(得分:1)

def printBook(d):
    del d['text']
    for i in d:
        if type(d[i]) == dict:
            if len(d[i])==1:
                d[i] = list(d[i].values())[0]
            else:
                d[i] = [('' if j=='text' else (j+':')) + d[i][j] for j in d[i]]
    s = '\n'
    for i,j in d.items():
        s += f' {i} : {j} ,\n'

    print(s)

尝试这些,它将单个词典打印为您描述的格式

答案 2 :(得分:1)

看看pprint模块,它提供了一种很好的方式来打印数据结构,而无需编写自己的格式化程序。

答案 3 :(得分:0)

感谢您的编码练习。伙计,该输出格式是特定的! :D Tricky,因为如果是独立的字符串则不加引号,如果来自text属性则加引号。同样棘手的是,这些东西必须扔进[]中,而不仅仅是text。另外,它还有点不足,因为嘿,如果根本没有text而又没有其他键怎么办?

输出格式免责声明:

  • 我认为,之后缺少'XQuery Kick Start'
  • 我认为应该引用Giada De Laurentiis,因为它来自'text'
import copy


def transform_value(stuff):
    if type(stuff) is str:
        return stuff
    if type(stuff) is dict:
        elements = []
        text = stuff.pop("text", "")
        if text:
            elements.append(f"'{text}'")  # we quote only if there was really a text entry
        if not stuff:  # dict just got empty
            return elements[0]  # no more attributes, so no [] needed around text
        elements.extend(f"'{key}': '{transform_value(value)}'" for key, value in stuff.items())
    if type(stuff) is list:
        elements = [transform_value(e) for e in stuff]
    # this will obviously raise an exception if stuff is not one of str, dict or list
    return f"[{', '.join(elements)}]"


def transform_pub(d: dict):
    d = copy.deepcopy(d)   # we are gonna delete keys, so we don't mess with the outer data
    tail = d.pop("text", "")
    result = ",\n".join(f'{key} : {transform_value(value)}' for key, value in d.items())
    return result + tail


if __name__ == "__main__":
    for sublist in data:
        for pub in sublist:
            print(transform_pub(pub))

我首先想通过某种递归以某种方式对出版物本身使用相同的机制。但是随后,由于text字段对于出版物是附加的,而对于属性来说是第一个,因此代码变得太复杂了。

一旦我放弃了完全结构化的解决方案,我就开始对发布打印机进行测试:

import pytest

from printing import transform_value


@pytest.mark.parametrize('input,output', [
    ("cooking", "cooking"),
    ({"text": "J K. Rowling"}, "'J K. Rowling'"),
    ({"lang": "en", "text": "Everyday Italian"},
     "['Everyday Italian', 'lang': 'en']"),
    ([{"text": "James McGovern"},
      {"text": "Per Bothner"},
      {"text": "Kurt Cagle"},
      {"text": "James Linn"},
      {"text": "Vaidyanathan Nagarajan"}],
     "['James McGovern', 'Per Bothner', 'Kurt Cagle', 'James Linn', 'Vaidyanathan Nagarajan']"
     ),
    ([{"text": "Joe"}], "['Joe']"),
    ({"a": "1"}, "['a': '1']"),
])
def test_transform_value(input, output):
    assert transform_value(input) == output