字典实战——在Python 3.X 和 2.7 中的字典改变——在3.X和2.7中的字典comprehension

未匹配的标注

在前一节末尾提到过:在3.X和2.7中的字典也可以被字典comprehension所创建。如同在第5章中碰到的set comprehension,字典comprehension只在3.X和2.7中可用。如同在第4章和本章早些时候中简短碰到过的长期存在的列表,它们运行一个隐式循环,对每次迭代收集键/值的结果,并使用它们来填充一个新字典。循环变量允许comprehension在此过程中使用循环迭代值。

为了说明,2.X和3.X中动态初始化字典的一个标准方法是使用zip组合其键和值,然后把结果传递给dict调用。zip内置函数是允许以这种方式(如果不能预测代码中键列表和值列表,可以将它们构建为列表然后压缩它们)从键列表和值列表来构建字典的钩子。将在第13章第14章中深入研究zip;在3.X中它是可迭代的,所以必须将其包裹在一个list调用中来显示它这里的结果,但基本用法相当简单:

>>> list(zip(['a', 'b', 'c'], [1, 2, 3])) # Zip together keys and values
[('a', 1), ('b', 2), ('c', 3)]
>>> D = dict(zip(['a', 'b', 'c'], [1, 2, 3])) # Make a dict from zip result
>>> D
{'b': 2, 'c': 3, 'a': 1}

然而,在 3.X 和 2.7中,可以使用字典comprehension表达式来达到同样效果。下面对zip结果(它在Python中看起来几乎是一样的,但有一点更正式)中的每一个对使用键/值对构建了一个新字典:

>>> D = {k: v for (k, v) in zip(['a', 'b', 'c'], [1, 2, 3])}
>>> D
{'b': 2, 'c': 3, 'a': 1}

在本例中,Comprehensions 其实需要更多代码,但它们也比本例所暗示的更通用——还可以用它们来映射一个单一的值流到字典,并且键可以像值那样使用表达式计算:

>>> D = {x: x ** 2 for x in [1, 2, 3, 4]} # Or: range(1, 5)
>>> D
{1: 1, 2: 4, 3: 9, 4: 16}
>>> D = {c: c * 4 for c in 'SPAM'} # Loop over any iterable
>>> D
{'S': 'SSSS', 'P': 'PPPP', 'A': 'AAAA', 'M': 'MMMM'}
>>> D = {c.lower(): c + '!' for c in ['SPAM', 'EGGS', 'HAM']}
>>> D
{'eggs': 'EGGS!', 'spam': 'SPAM!', 'ham': 'HAM!'}

字典comprehensions还对从键列表初始化字典很有用,很像在前一节末尾碰到的fromkeys方法:

>>> D = dict.fromkeys(['a', 'b', 'c'], 0) # Initialize dict from keys
>>> D
{'b': 0, 'c': 0, 'a': 0}
>>> D = {k:0 for k in ['a', 'b', 'c']} # Same, but with a comprehension
>>> D
{'b': 0, 'c': 0, 'a': 0}
>>> D = dict.fromkeys('spam') # Other iterables, default value
>>> D
{'s': None, 'p': None, 'a': None, 'm': None}
>>> D = {k: None for k in 'spam'}
>>> D
{'s': None, 'p': None, 'a': None, 'm': None}

像相关工具一样,字典comprehension支持未在这里展示的额外语法,包括嵌套循环和if从句。不幸的是,要真正理解字典comprehension,需要还知道更多关于Python的迭代语句和概念的知识,目前还没有足够的信息来处理好这个故事。将在第14章第20章中学习更多关于comprehension所有类型(列表,set,字典,生成器)的知识,所以把进一步细节推迟到稍后。还将在第13章当探索for循环时,更详细地重温本节使用的zip内置函数。

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
讨论数量: 0
发起讨论 查看所有版本


暂无话题~