Python 可变容器的mutator方法(例如.reverse
列表的方法)几乎总是返回None
- 少数返回一个有用的值,例如该.pop
方法返回弹出的元素,但要保留的关键概念是这些 mutator 都不会返回 mutated容器:相反,容器就地变异,而变异器方法的返回值不是那个容器。(这是CQS设计原则的应用——不像 Eiffel 那样狂热,Eiffel 是由同时发明 CQS 的 Bertrand Meyer 设计的语言,但这仅仅是因为在 Python 中“实用性胜过纯粹性,cfr import this
;- )。
构建一个列表通常比构建一个迭代器更昂贵,因为在绝大多数情况下,你想要做的只是循环结果;因此,诸如reversed
(以及模块中所有出色的构建块itertools
)之类的内置函数返回的是迭代器,而不是列表。
但是,如果您因此有一个迭代器x
但真的需要等效列表 y
怎么办?小菜一碟——做吧y = list(x)
。要创建 type 的新实例list
,您可以调用type list
——这是一个通用的 Python 思想,保留比我在前两段中指出的非常重要的东西更重要!-)
因此,根据前面段落中的关键概念,您的特定问题的代码非常容易组合:
[list(reversed(row)) for row in figure]
请注意,我使用的是列表推导,而不是 map
:根据经验,仅当不需要a来构建它map
时才应将其用作最后的优化(如果涉及 a,则使用 listcomp,以及像往常一样更清晰,无论如何也往往更快!-)。lambda
lambda
一旦你成为“过去的 Python 大师”,如果你的分析告诉你这段代码是一个瓶颈,你就可以知道尝试替代方案,例如
[row[::-1] for row in figure]
应用负步切片(又名“火星笑脸”)来制作行的反向副本,知道它通常比list(reversed(row))
方法更快。但是——除非你的代码只能由你自己或至少与 Python 一样熟练的人来维护——否则使用最简单的“来自第一原理的代码”方法是一个合理的立场,除非分析告诉你踩下踏板. (我个人认为“火星笑脸”非常重要,可以避免将这种良好的一般哲学应用于这个特定的用例,但是,嘿,理性的人可能会在这个非常具体的点上有所不同!-)。