我有一个字典列表:
dictlist = [{'key1':'value1', 'key2':'value2'}, {'key3':'value3', 'key4':'value4'}]
我目前像这样打印键值对:
for d in dictlist:
for key in d:
print .format('{} ---> {}').format(key,d[key])
如何使用生成器表达式来减少代码行数?
编辑:我正在尝试熟悉生成器表达式,而不仅仅是减少代码行!
请您参考如下方法:
看看 python docs on expressions .这些都是代表各种复杂性的一种或另一种值(value)的东西。它们不是引发副作用的事物(如 I/O)或对可变数据的转换。生成器表达式,顾名思义,只是另一种表达式。
减少代码行不是生成器表达式的预期目的。除了“内存效率和惰性计算值”(感谢下面的评论者)的主要用途之外,它们的很大一部分目的是通过使迭代器成为一种更易于访问的原子值来使您的代码更简洁和可读。如果您使代码的可读性降低,则可能是您错误地使用了生成器表达式。
在我看来,尤其是生成器表达式与 Python 编程的函数式范式 紧密相关。它们产生的值与您从数学定义的系列中期望的一样,例如 产生所有斐波那契数的生成器。考虑到这种功能范式,专门使用生成器来产生副作用可能是一种代码味道。
积极地说,使用生成器表达式的正确方法可能是让它们一次对可迭代数据集的一个元素执行一个定义明确的转换,并生成转换后的数据然后。这符合函数范式:函数接受一个值,返回一个值,并且没有副作用。
您可以使用生成器函数 以一种有趣的方式重构此代码,这将允许您通过遍历生成的元素来打印连续的元素。像这样:
def my_printer(dictlist):
for d int dictlist: # renamed to not shadow dict
for key in dict:
print .format('{} ---> {}').format(key,dict[key])
yield
然后你可以打印如下元素:
>>> p = my_printer(dictlist)
>>> p.next()
'some stuff 1'
>>> p.next()
'some stuff 2'
等等
但这并不是您真正要求的。
为了更直接地回答您的问题,如果您将 print 语句排除在外,您可能会得到一些看起来像是嵌套的 for 循环的扁平化:
>>> (('{} ---> {}').format(k,v) for d in dictlist for k,v in d.items())
或者实际上,由于 (k,v) 只是一个元组,您以相同的顺序传递,您可以使用 splat 运算符 * 直接将其解包为参数到您的 format 调用中:
>>> (('{} ---> {}').format(*p) for d in dictlist for p in d.items())
最后,您可能希望通过使用 iteritems 函数来移除 d.items() 的中间列表创建:
>>> (('{} ---> {}').format(*p) for d in dictlist for p in d.iteritems())
然后使用常规的 for 循环打印结果:
>>> for x in _:
print x
key2 ---> value2
key1 ---> value1
key3 ---> value3
key4 ---> value4
