Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 我可以使用生成器表达式打印字典列表的键、值对吗?_Python_Dictionary_List Comprehension_Generator Expression - Fatal编程技术网

Python 我可以使用生成器表达式打印字典列表的键、值对吗?

Python 我可以使用生成器表达式打印字典列表的键、值对吗?,python,dictionary,list-comprehension,generator-expression,Python,Dictionary,List Comprehension,Generator Expression,我有一份字典清单: dictlist = [{'key1':'value1', 'key2':'value2'}, {'key3':'value3', 'key4':'value4'}] 我当前打印键、值对,如下所示: for d in dictlist: for key in d: print .format('{} ---> {}').format(key,d[key]) 如何使用生成器表达式减少代码行数 编辑:我试图熟悉生成器表达式,而不仅仅是减少代码行数 您可以使用

我有一份字典清单:

dictlist = [{'key1':'value1', 'key2':'value2'}, {'key3':'value3', 'key4':'value4'}]
我当前打印键、值对,如下所示:

for d in dictlist:
  for key in d:
    print .format('{} ---> {}').format(key,d[key])
如何使用生成器表达式减少代码行数


编辑:我试图熟悉生成器表达式,而不仅仅是减少代码行数

您可以使用生成器表达式和
itertools
对其进行一行操作

from itertools import chain, imap

print '\n'.join('{} ---> {}'.format(k,v) for k, v in chain.from_iterable(d.iteritems() for d in dictlist))

d.itervalues()
返回每个字典中所有值的生成器
itertools.chain
获取所有这些生成器,并将它们扁平化为单个生成器。
itertools.imap
函数将所有值转换为字符串,以便打印。然后,这些值被送入
.join
方法,该方法在每个值之间放置一条换行符并打印出来。

您可以使用生成器表达式,并将
itertools
转换为一行

from itertools import chain, imap

print '\n'.join('{} ---> {}'.format(k,v) for k, v in chain.from_iterable(d.iteritems() for d in dictlist))

d.itervalues()
返回每个字典中所有值的生成器
itertools.chain
获取所有这些生成器,并将它们扁平化为单个生成器。
itertools.imap
函数将所有值转换为字符串,以便打印。然后将这些值输入到
.join
方法,该方法在每个值之间放置一条换行符并打印出来。

将代码设置为水平而不是垂直并没有什么实际好处,但您可以按如下方式操作:

from __future__ import print_function
from itertools import imap
print(*(' ---> '.join(imap(str, item)) for dic in dictlist for item in dic.iteritems()), sep='\n')
结果:

key2 ---> value2
key1 ---> value1
key3 ---> value3
key4 ---> value4

请注意,
map()
用于将非字符串元素转换为字符串,以便它们可以与
join()
连接。如果您确信键和值始终是字符串,则可以简单地使用
'-->'.join(item)

将代码设置为水平而不是垂直不会带来任何实际好处,但您可以按如下方式操作:

from __future__ import print_function
from itertools import imap
print(*(' ---> '.join(imap(str, item)) for dic in dictlist for item in dic.iteritems()), sep='\n')
结果:

key2 ---> value2
key1 ---> value1
key3 ---> value3
key4 ---> value4

请注意,
map()
用于将非字符串元素转换为字符串,以便它们可以与
join()
连接。如果您确信键和值始终是字符串,那么您可以简单地使用
'-->'.join(item)

嗯,您拥有的可能是最可读的版本。我可能会同意

但是如果您想要更紧凑的版本,那么:

>>> dictlist = [{'key1':'value1', 'key2':'value2'}, {'key3':'value3', 'key4':'value4'}]
>>> list((k,v) for d in dictlist for k,v in d.iteritems())
[('key2', 'value2'), ('key1', 'value1'), ('key3', 'value3'), ('key4', 'value4')]

注意:最外层的
列表仅是一个占位符。你应该调用一个函数来代替它。

嗯,你所拥有的可能是最可读的版本。我可能会同意

但是如果您想要更紧凑的版本,那么:

>>> dictlist = [{'key1':'value1', 'key2':'value2'}, {'key3':'value3', 'key4':'value4'}]
>>> list((k,v) for d in dictlist for k,v in d.iteritems())
[('key2', 'value2'), ('key1', 'value1'), ('key3', 'value3'), ('key4', 'value4')]
注意:最外层的
列表仅是一个占位符。您应该调用并放置一个函数调用。

如果您真的想,您可以迭代一个生成器表达式来打印内容本身,只需放弃您迭代的内容:

for _ in (print('{} ---> {}'.format(key,dict[key])) for dict in dictlist for key in dict):
    pass
我真的看不出有什么理由这么做,尽管它不是很可读。它假设Python 3,或来自uuu future uuuu导入print u函数的
,因此您可以在表达式中使用
print。

如果您确实愿意,您可以迭代打印内容本身的生成器表达式,只需放弃您迭代的内容:

for _ in (print('{} ---> {}'.format(key,dict[key])) for dict in dictlist for key in dict):
    pass
我真的看不出有什么理由这么做,尽管它不是很可读。它采用Python 3,或来自uuu future uuuu导入print u函数的
,因此您可以在表达式中使用
print

查看。这些都只是代表了各种各样的复杂价值观。它们不是对可变数据产生副作用的东西(如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(*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
请看下面的图片。这些都只是代表了各种各样的复杂价值观。他们