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

Как получить фильтр для работы с лямбдой с несколькими аргументами?

Используя Python, мне трудно заставить filter() работать с лямбдой для случаев, когда необходимо передать более одного аргумента, как в следующем фрагменте:

max_validation = lambda x,y,z: x < y < z
sequence1 = [1,4,8]
filter(max_validation, sequence1)

Возникает следующая ошибка:

TypeError: <lambda>() takes exactly 3 arguments (1 given)

Пожалуйста, представьте, что я здесь делаю неправильно.

4b9b3361

Ответ 1

Немного сложно понять, что именно вы пытаетесь сделать. Я собираюсь интерпретировать ваш вопрос, а затем дать ответ. Если это неверно, измените свой вопрос или ответьте на этот ответ.

Вопрос

У меня есть последовательности, которые имеют ровно три элемента. Здесь один:

sequence1 = [1, 4, 8]

Я хочу убедиться, что первый элемент меньше второго элемента, который, в свою очередь, должен быть меньше третьего элемента. Для этого я написал следующую функцию:

max_validation = lambda x, y, z: x < y < z

Как применить это с помощью filter? Использование filter(max_validation, sequence1) не работает.

Ответ

Фильтр применяет вашу функцию к каждому элементу предоставленного итерации, выбирая ее, если функция возвращает True и отбрасывает ее, если функция возвращает False.

В вашем случае filter сначала смотрит на значение 1. Он пытается передать это в вашу функцию. Ваша функция ожидает три аргумента, и предоставляется только одна, поэтому это не удается.

Вам нужно сделать два изменения. Сначала введите трехэлементную последовательность в список или другую последовательность.

sequences = [[1, 4, 8], [2, 3, 9], [3, 2, 3]]
max_validation = lambda x: x[0] < x[1] < x[2] and len(x) == 3

Я добавил две другие последовательности для тестирования. Поскольку sequences - список списка, каждый список передается вашей тестовой функции. Даже если вы тестируете только одну последовательность, вы должны использовать [[1, 4, 8]], чтобы вся тестовая последовательность передавалась в вашу функцию.

Я также изменил max_validation, чтобы он принял только один аргумент: список для проверки. Я также добавил and len(x) == 3, чтобы гарантировать, что последовательности состоят только из трех элементов длиной

Ответ 2

Функция, переданная в filter(), получает только один переданный ей аргумент, который является текущим элементом в итерабельном повторении. Если вам нужно что-то более интересное, чем то, то filter() не будет делать.

Ответ 3

Это можно сделать с помощью замыкания:

>>> def foo(a,b):
...   def bar(c):
...     return a+b+c
...   return bar
... 
>>> x = foo(1,2)
>>> x(3)
6
>>> y = foo(100,0)
>>> y(1)
101
>>> x(1)
4

Ответ 4

Надеюсь, вы знаете?

>>> max([1, 4, 8])
8

filter() принимает один аргумент. В вашем случае это займет 1. Тогда 4. Тогда 8.

Ответ 5

Прямо из документов Python Filters

Обратите внимание, что фильтр (функция, итерация)эквивалентно [item для элемента в iterable if function (item)] if функция не является None и [item for item in iterable if item] если функция Нет.

Итак, вы можете просто обрабатывать одиночные аргументы с фильтрами Python. Это означает, что вы не можете использовать фильтры для своего примера. Вам нужно будет написать собственный код для него.

Ответ 6

Это будет работать для последовательностей любой длины:

all(x < y for x, y in zip(seq, seq[1:]))

Что происходит?

Для последовательности 1, 2, 3... вы берете последовательности 1, 2, 3... и 2, 3, 4... и застегиваете их вместе в последовательность (1, 2), (2, 3),... Затем вы проверяете, есть ли инструкция 'x < y 'выполняется для каждой пары.

И это будет работать для любого ассоциативного правила, которое вы хотите проверить.

Полезные ссылки:

Ответ 7

Я думаю, что все остальные не поняли. сообщение об ошибке для лямбда-функции не для фильтра. Вы должны называть это следующим образом:

filter(max_validation, *sequence1)

добавить звезду в списке, превратить ее в три аргумента, тогда она будет работать.

Ответ 8

Вы можете изменить

max_validation = lambda x,y,z: x < y < z

к

max_validation = lambda (x,y,z): x < y < z

Ответ 9

Я согласен с обоими @walkingpendulum и @Wesley, в зависимости от интерпретации фактической постановки задачи. Итак, разобравшись в двусмысленности в постановке проблемы: Если вы последовательно сравниваете один элемент с его предыдущим значением в итерируемом объекте, выражение лямбда является излишним, просто используйте понимание списка:

[1 if i < i+1 else 0 for i in sequence1]

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

sequence1 == some_other_sequence

и

x, y, z = 1, 2, 3
x < y < z

И, наконец, если вы хотите применить лямбда-выражение к итерируемому объекту, карта может получить вас там: (произвольная лямбда-функция)

map(lambda x: x > 1, sequence1)

В противном случае @walkingpendulum и @Wesley охватывают другие интерпретации