什么是迭代dicts和列表的Pythonic方法?

时间:2012-04-03 02:00:25

标签: python dictionary

我有一个包含一些列表和一些词典的词典,如下图所示。

迭代dict并打印出每个顶级字典键的名称和地址对的最pythonic方法是什么?

由于

{
    'Resent-Bcc': [],
    'Delivered-To': [],
    'From': {'Name': 'Steve Watson', 'Address': 'steve.watson@example.org'},
    'Cc': [],
    'Resent-Cc': [],
    'Bcc': [ {'Name': 'Daryl Hurstbridge', 'Address': 'daryl.hurstbridge@example.org'},
             {'Name': 'Sally Hervorth', 'Address': 'sally.hervorth@example.org'},
             {'Name': 'Mike Merry', 'Address': 'mike.merry@example.org'},
             {'Name': 'Jenny Callisto', 'Address': 'jenny.callisto@example.org'}
           ],
    'To': {'Name': 'Darius Jedburgh', 'Address': 'darius.jedburgh@example.org'}
}

5 个答案:

答案 0 :(得分:3)

在dict上使用iteritems()方法。它清晰易懂:对我而言似乎是Pythonic。正如Preet Kukreti在评论中提到的那样,iteritems()创建的临时项目也少于items()。首先,修复您的数据。现在,顶级字典中的一些值是列表,有些是更多的字符串:

# list
'Delivered-To': [],
# dict
'From': {'Name': 'Steve Watson', 'Address': 'steve.watson@example.org'},

这意味着您必须检查值的类型并采取相应的行动(您可能忘记检查!)。使您的数据保持一致:

# list
'Delivered-To': [],
# also list
'From': [{'Name': 'Steve Watson', 'Address': 'steve.watson@example.org'}],

这将防止将来出现与奇怪类型相关的错误。由于Python是一种解释型语言,因此在您的代码处于生产和崩溃之前,很容易产生类型错误而不会注意到。尽量使您的代码尽可能类型安全!

然后你可以使用这样的东西:

for k, v in d.iteritems():
  for row in v:
    if "Name" in row and "Address" in row:
      print row["Name"], ":", row["Address"]

答案 1 :(得分:2)

一种方法是将单独的dicts更改为包含dict的列表。然后可以对所有条目进行相同的处理

>>> D = {
...     'Resent-Bcc': [],
...     'Delivered-To': [],
...     'From': {'Name': 'Steve Watson', 'Address': 'steve.watson@example.org'},
...     'Cc': [],
...     'Resent-Cc': [],
...     'Bcc': [ {'Name': 'Daryl Hurstbridge', 'Address': 'daryl.hurstbridge@example.org'},
...              {'Name': 'Sally Hervorth', 'Address': 'sally.hervorth@example.org'},
...              {'Name': 'Mike Merry', 'Address': 'mike.merry@example.org'},
...              {'Name': 'Jenny Callisto', 'Address': 'jenny.callisto@example.org'}
...            ],
...     'To': {'Name': 'Darius Jedburgh', 'Address': 'darius.jedburgh@example.org'}
... }
>>> L = [v if type(v) is list else [v] for v in D.values()]
>>> [(d["Name"], d["Address"]) for item in L for d in item ]
[('Steve Watson', 'steve.watson@example.org'), ('Daryl Hurstbridge', 'daryl.hurstbridge@example.org'), ('Sally Hervorth', 'sally.hervorth@example.org'), ('Mike Merry', 'mike.merry@example.org'), ('Jenny Callisto', 'jenny.callisto@example.org'), ('Darius Jedburgh', 'darius.jedburgh@example.org')]

或单线版

[(d["Name"], d["Address"]) for item in (v if type(v) is list else [v] for v in D.values())]

答案 2 :(得分:1)

最好保持数据简单,使裸字典是一个包含原始字典的元素的列表。否则,你会更难以测试代码。

我倾向于偏离isinstance(foo,dict),而是使用以下内容: if getattr(d,'iteritems'):print list(d.iteritems())

......这种方式让我感觉更像鸭子;它打开了使用许多字典替换之一的大门 - 这些东西就像一个字典,但名义上不是字典。

答案 3 :(得分:0)

for key in header:
    if header[key] and type(header[key])==type([]):
        for item in header[key]:
            print (item)
    elif type(header[key])==type({}):
        print(header[key])

# this option is not the easiest to read, so I classify it as less "pythonic"       
l = [header[key] for key in header if header[key] and type(header[key])==type({})] + [header[key][i] for key in header if header[key] and type(header[key])==type([]) for i in range(len(header[key]))]
for item in l:
    print(item)

如果您正在查找特定标头的内容,则可以相应地修改if语句。这两个例子都打印了字典,但很容易适应打印特定值。

答案 4 :(得分:-1)

for i in dict:
   if 'Name' in dict[i]: 
      print (dict[i]['Name'],dict[i]['Address'])

这不适用于列表中的bcc(现在它只会打印from和to name和地址)你是否还需要它来打印bcc地址?