Создание лямбда-функции Python из последовательности строк - PullRequest
0 голосов
/ 23 июня 2018

У меня есть список из m элементов и n разных номеров, которые появляются в списке строк. Список следует следующему примеру формата

eq = ['12', '2', '3', '-123', '-1', 'X']

Обратите внимание, X представляет собой константу 1, отличную от переменной 1. Я хочу иметь возможность преобразовать ее в лямбда-функцию, которая принимает список x и действует так, как будто этот список суммировался вместе. Для нашего примера функция будет

f(x) = x[1]*x[2] + x[2] + x[3] - x[1]*x[2]*x[3] - x[1] + 1

Я знаю, как это сделать с помощью обычной функции, но я хотел, чтобы она работала с лямбдой и ударилась о стену. Любая помощь будет оценена!

Вот функция, которая работает для проблемы:

def evaluateList(x, lst):
    num = 0
    for term in lst:
        if term[0] == "X":
            num += 1
        elif term[0] == "-":
            num -= reduce(lambda x,y: x*y, [x[int(y)-1] for y in term[1:]])
        else:
            num += reduce(lambda x,y: x*y, [x[int(y)-1] for y in term])
    return num

Ответы [ 4 ]

0 голосов
/ 23 июня 2018

Очевидно, я рекомендую реализацию def:

from functools import reduce

eq = ['12', '2', '3', '-123', '-1', 'X']
x = [n for n in range(100)]

# Using an auxiliary function
def evaluate(n):
    if n == "X":
        return 1
    elif n[0] == "-":
        return reduce(lambda x, y: x * y, [x[int(y) - 1] for y in n[1:]])
    else:
        return reduce(lambda x, y: x * y, [x[int(y) - 1] for y in n])

print(sum(map(evaluate, eq)))

# As a pure lambda:

evaluate_lambda = lambda n: sum(map((lambda n: 1 if n == 'X' else (reduce(lambda x, y: x * y, [x[int(y) - 1] for y in n[1:]]) if n[0] == "-" else reduce(lambda x, y: x * y, [x[int(y) - 1] for y in n]))), eq))

print(evaluate_lambda(eq))
0 голосов
/ 23 июня 2018

это немного уродливо, но работает

from operator import mul
a = lambda eq: sum([reduce(mul, [int(x) if x.isdigit() else [1,-1][x=='-'] for x in s]) for s in eq])


print(a(['12', '2', '3', '-123', '-1', 'X']))  # outputs 1
print(a(['126', '32', '3', '-2', 'X']))  # outputs 20

edit: конечно, это всего лишь игра.всегда используйте самую читаемую функцию

0 голосов
/ 23 июня 2018

Я думаю, что это достаточно просто:

from operator import mul
from functools import reduce
prod = lambda L: reduce(mul, L, 1)
evaluateList = lambda(x, eq): sum(
    1 if expr == 'X' 
    else prod(-1 if i == '-' 
              else x[int(i)] 
              for i in expr) 
    for expr in eq)
0 голосов
/ 23 июня 2018

Вы можете использовать functools.reduce дважды, хотя результат не очень чистый:

from functools import reduce
from operator import sub, add
eq = ['12', '2', '3', '-123', '-1', 'X']
_x = [6, 4, 1, 4, 5, 2, 4, 23, 2, 4]
final_result = reduce(lambda x, y:[add, sub][y.startswith('-')](
  reduce(lambda c, d:c*d, [_x[int(i)] for i in x]) if x in eq else x, 
  reduce(lambda c, d:c*d, [_x[int(i)] for i in (y[1:] if y.startswith('-') else y)] if y != 'X' else [1])
  ), eq)

print(final_result)
x = _x
print(x[1]*x[2] + x[2] + x[3] - x[1]*x[2]*x[3] - x[1] + 1)

Выход:

-10
-10

Но опять же, предопределенную функцию гораздо легче читать и масштабировать.

Также, немного короче, с sum:

new_result = sum([1, -1][i.startswith('-')]*reduce(lambda x, y:x*y, [1] if i == 'X' else [x[int(c)] for c in (i[1:] if i.startswith('-') else i)]) for i in eq)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...