Сопоставление вложенного списка с пониманием списка в Python?

У меня есть следующий код, который я использую для отображения вложенного списка в Python для создания списка с той же структурой.

>>> nested_list = [['Hello', 'World'], ['Goodbye', 'World']]
>>> [map(str.upper, x) for x in nested_list]
[['HELLO', 'WORLD'], ['GOODBYE', 'WORLD']]

Можно ли это сделать только с помощью понимания списка (без использования функции карты)?


person kjfletch    schedule 20.08.2009    source источник


Ответы (5)


Для вложенных списков вы можете использовать вложенные списки:

nested_list = [[s.upper() for s in xs] for xs in nested_list]

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

person Eli Courtwright    schedule 20.08.2009
comment
в карте py3k требуется применить к ней список. - person SilentGhost; 20.08.2009

Помните дзен Python:

Как правило, существует более одного — а возможно, и несколько — очевидных способов сделать это**.

** Примечание: отредактировано для точности.

В любом случае, я предпочитаю карту.

from functools import partial
nested_list = map( partial(map, str.upper), nested_list )
person Stuart Berg    schedule 14.03.2013
comment
Ух ты. По-видимому, моя маленькая шутка о дзен-питоне действительно задела чьи-то чувства (и, следовательно, отрицательный голос). Просветитесь, люди! (FWIW, я на 100% искренен в использовании map в этом случае.) - person Stuart Berg; 24.10.2016
comment
Должно быть [...], +1 за правду х-) - person Edouard; 11.01.2017

Карта, безусловно, гораздо более чистый способ делать то, что вы хотите. Однако вы можете вложить понимание списка, может быть, это то, что вам нужно?

[[ix.upper() for ix in x] for x in nested_list]
person KayEss    schedule 20.08.2009
comment
Да, с картой может быть чище, но я бы хотел использовать генератор. - person kjfletch; 20.08.2009

Вот решение для вложенного списка произвольной глубины:

def map_nlist(nlist=nlist,fun=lambda x: x*2):
    new_list=[]
    for i in range(len(nlist)):
        if isinstance(nlist[i],list):
            new_list += [map_nlist(nlist[i],fun)]
        else:
            new_list += [fun(nlist[i])]
    return new_list

вы хотите, чтобы все перечисленные вами элементы были в верхнем регистре, просто введите

In [26]: nested_list = [['Hello', 'World'], ['Goodbye', [['World']]]]
In [27]: map_nlist(nested_list,fun=str.upper)
Out[27]: [['HELLO', 'WORLD'], ['GOODBYE', [['WORLD']]]]

И что более важно, эта рекурсивная функция может сделать больше!

Я новичок в python, не стесняйтесь обсуждать!

person Oldyoung    schedule 01.10.2014
comment
Используйте append вместо +=, чтобы избежать повторного создания нового списка для каждого элемента. - person Ioannis Filippidis; 18.06.2015
comment
@IoannisFilippidis Filippidis Привет, спасибо за ответ, но не могли бы вы рассказать мне подробнее о проблеме с +=? Я не совсем понимаю разницу... (давно не использую python..) - person Oldyoung; 21.01.2016
comment
Пусть a = list(). С помощью a.append(0) тот же экземпляр list расширяется еще одним элементом. Напротив, a += [0] создает один новый список [0], который затем удаляется из памяти. Исправление к моему предыдущему комментарию: я думал, что __iadd__ работает так же, как __add__, но использование id показало, что это не так. Более подробную информацию можно найти здесь. - person Ioannis Filippidis; 25.01.2016
comment
Это действительно умно! - person MaxU; 28.12.2016

Другие авторы дали ответ, но всякий раз, когда у меня возникают проблемы с пониманием функциональной конструкции, я проглатываю свою гордость и излагаю ее от руки с явно неоптимальными методами и/или объектами. Вы сказали, что хотите получить генератор, поэтому:

for xs in n_l:
    def doUpper(l):
        for x in l:
            yield x.upper()
    yield doUpper(xs)

for xs in n_l:
    yield (x.upper() for x in xs)

((x.upper() for x in xs) for xs in n_l)

Иногда лучше оставить одну из полных версий. Для меня map и reduce иногда делают это более очевидным, но идиомы Python могут быть более очевидными для других.

person Karl Anderson    schedule 20.08.2009