11

我想做这样的事情,但是这段代码返回 None 列表(我认为这是因为 list.reverse() 正在反转列表):

map(lambda row: row.reverse(), figure)

我试过这个,但反向返回一个迭代器:

map(reversed, figure)

最后我做了这样的事情,这对我有用,但我不知道这是否是正确的解决方案:

def reverse(row):
    """func that reverse a list not in place"""
    row.reverse()
    return row

map(reverse, figure)

如果有人有我不知道的更好的解决方案,请告诉我

亲切的问候,

4

5 回答 5

27

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,以及像往常一样更清晰,无论如何也往往更快!-)。lambdalambda

一旦你成为“过去的 Python 大师”,如果你的分析告诉你这段代码是一个瓶颈,你就可以知道尝试替代方案,例如

[row[::-1] for row in figure]

应用负步切片(又名“火星笑脸”)来制作行的反向副本,知道它通常比list(reversed(row))方法更快。但是——除非你的代码只能由你自己或至少与 Python 一样熟练的人来维护——否则使用最简单的“来自第一原理的代码”方法是一个合理的立场,除非分析告诉你踩下踏板. (我个人认为“火星笑脸”非常重要,可以避免将这种良好的一般哲学应用于这个特定的用例,但是,嘿,理性的人可能会在这个非常具体的点上有所不同!-)。

于 2010-09-25T16:54:56.387 回答
8

您还可以使用切片来反转单个列表(到位):

>>> a = [1,2,3,4]
>>> a[::-1]
[4, 3, 2, 1]

所以像:

all_reversed = [lst[::-1] for lst in figure]

...或者...

all_reversed = map(lambda x: x[::-1], figure)

...会做你想做的事。

于 2010-09-25T16:29:15.400 回答
3
reversed_lists = [list(reversed(x)) for x in figure]
于 2010-09-25T16:09:15.947 回答
1
map(lambda row: list(reversed(row)), figure)
于 2010-09-25T16:07:34.970 回答
0

你也可以简单地做

for row in figure:
    row.reverse()

更改每一行。

于 2010-09-25T18:04:40.820 回答