Подтвердить что ты не робот

Почему я не могу отменить список списков в python

Я хотел сделать что-то вроде этого, но этот код возвращает список 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)

Если у кого-то есть лучшее решение, о котором я не знаю, сообщите мне

С уважением,

4b9b3361

Ответ 1

Мутаторные методы изменяемых контейнеров Python (например, метод списков .reverse) почти неизменно возвращают None - несколько возвращают одно полезное значение, например. метод .pop возвращает всплывающий элемент, но ключевая концепция для сохранения заключается в том, что ни один из этих мутаторов не возвращает мутированный контейнер: скорее, контейнер мутирует на месте, а возвращаемое значение метода мутатора это не тот контейнер. (Это приложение принципа CQS - не столь фанатичного, как, скажем, в Эйфеле, язык, разработанный Бертран Мейер, который также изобрел CQS, но это только потому, что в Python "практичность превосходит чистоту, cfr import this; -).

Построение списка часто более дорогостоящее, чем просто создание итератора, для подавляющего большинства случаев, когда все, что вы хотите сделать, - это цикл результата; поэтому встроенные элементы, такие как reversed (и все замечательные строительные блоки в модуле itertools), возвращают итераторы, а не списки.

Но что, если у вас поэтому есть итератор x, но действительно нужен эквивалентный список y? Кусок торта - просто сделай y = list(x). Чтобы создать новый экземпляр типа list, вы вызываете тип list - это такая общая идея Python, что еще более важно сохранить, чем довольно важный материал, который я указал в первых двух абзацах! -)

Таким образом, код для вашей конкретной проблемы действительно очень легко собрать на основе ключевых понятий в предыдущих параграфах:

[list(reversed(row)) for row in figure]

Обратите внимание, что я использую понимание списка, не map: как правило, map следует использовать только как последнюю оптимизацию, если нет необходимости a lambda, чтобы его построить (если задействован lambda, то listcomp, а также более ясный, как обычно, также имеет тенденцию быть быстрее в любом случае! -).

Как только вы являетесь "прошлым мастером Python", если ваше профилирование говорит вам, что этот код является узким местом, вы можете узнать, как попробовать альтернативы, такие как

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

применяя срез с отрицательным шагом (он же "Марсианский смайлик" ) для создания обратных копий строк, зная, что он обычно быстрее, чем подход list(reversed(row)). Но - если ваш код не должен поддерживаться только самим собой или кем-то, по крайней мере, как опытный на Python, - это оправданное положение для использования простейшего подхода "код из первых принципов", за исключением случаев, когда профилирование говорит вам о нажатии на педаль, (Лично я думаю, что "Марсианский смайлик" достаточно важен, чтобы не применять эту хорошую общую философию к этому конкретному варианту использования, но, эй, разумные люди могут отличаться в этом конкретном месте! -).

Ответ 2

Вы также можете использовать срез, чтобы получить разворот одного списка (не на месте):

>>> 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)

... сделает то, что вы хотите.

Ответ 3

reversed_lists = [list(reversed(x)) for x in figure]

Ответ 4

map(lambda row: list(reversed(row)), figure)

Ответ 5

Вы также можете просто сделать

for row in figure:
    row.reverse()

чтобы изменить каждую строку на месте.