Карта с лямбда-функцией, которая принимает два параметра - PullRequest
0 голосов
/ 09 января 2019

Я хотел бы получить i-й элемент из всех подсписков в списке списков. Я попытался использовать функцию map и lambda, как показано ниже

extract = lambda x,i :x[i]
a = [[1,2,3],[4,5,6],[6,7,8]]
b = list(map(extract(i = 1),a))

Я ожидаю, что b будет [2,5,7] но я знаю, что последняя строка не работает. Как мне подходить к этому с картой и лямбда

Ответы [ 5 ]

0 голосов
/ 09 января 2019

Я также голосую за решение «за». Синтаксис функционального программирования выглядит красиво, но иногда это слишком много.

a = [[1,2,3],[4,5,6],[6,7,8]]
b = list(map(lambda x: x[1], a)) #  Brr, how many types conversions involved
c = [x[1] for x in a] # Looks more lightweight

Давайте просто проверим:

import timeit
timeit.timeit('a = [[1,2,3],[4,5,6],[6,7,8]]; b = [x[1] for x in a]', number=10000)
> 0.01244497299194336
timeit.timeit('a = [[1,2,3],[4,5,6],[6,7,8]]; b = list(map(lambda x: x[1], a))', number=10000)
> 0.021031856536865234

в 2 раза медленнее.

0 голосов
/ 09 января 2019

Вы не должны жестко кодировать индекс.

ИМХО, вы должны вернуть лямбда-функцию из метода extract, выполнив что-то вроде этого:

def extract(i):
    return lambda x : x[i]

a = [[1,2,3],[4,5,6],[6,7,8]]

b = list(map(extract(1), a))

print(b)          

Выход:

[2, 5, 7]      

Примечание. Лучшим (читай питонским) подходом будет использование понимания списка следующим образом:

a = [[1,2,3],[4,5,6],[6,7,8]]

b = [li[1] for li in a]

print(b)
0 голосов
/ 09 января 2019

Вы можете ввести жесткий код в 1:

extract = lambda x: x[1]
a = [[1,2,3],[4,5,6],[6,7,8]]
b = list(map(extract,a))

print(b)
# [2, 5, 7]

Обычно вы не хотите хранить lambda в переменной, это лучше:

def extract(x):
    return x[1]

b = list(map(extract, a))

Или просто так:

b = list(map(lambda x: x[1], a))

Вы также можете использовать понимание списка, которое я лично считаю лучшим вариантом:

c = [x[1] for x in a]

print(b == c)
True
0 голосов
/ 09 января 2019

Проблема , лежащая в основе , заключается в том, что ваш первый аргумент функции должен быть указан при вызове extract. Это возможно через functools.partial:

from functools import partial
b = list(map(partial(extract, i=1), a))  # [2, 5, 7]

Но это относительно неэффективно, поскольку для каждой итерации создается a новая функция. Вместо этого, как советовали другие, используйте operator.itemgetter:

from operator import itemgetter
b = list(map(itemgetter(1), a))          # [2, 5, 7]

Кроме того, PEP 8 не рекомендует именовать функции lambda; вместо этого определите явно:

def extract(x, i):
    return x[i]
0 голосов
/ 09 января 2019

Я бы предложил использовать operator.itemgetter здесь, чтобы получить второй элемент каждого подсписка:

from operator import itemgetter

a = [[1,2,3],[4,5,6],[6,7,8]]

print(list(map(itemgetter(1), a)))
# [2, 5, 7]

Или используя lambda:

a = [[1,2,3],[4,5,6],[6,7,8]]

print(list(map(lambda x: x[1], a)))
# [2, 5, 7]

Ваша анонимная функция:

extract = lambda x,i :x[i]

Необходимо вместо этого сопоставить конкретно индекс:

extract = lambda x: x[1]

Затем вы можете просто сопоставить эту функцию со своим списком с помощью map(extract(1), a).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...