2014-02-20 3 views
1

Я пытаюсь «продолжить» мою одну подкладку и наткнулся на этот бит. Просто использовать некоторое время было бы достаточно, если бы я не запретил себе использовать несколько строк.Создание списка до тех пор, пока определенное условие не будет выполнено с использованием одной строки

Таким образом, проблема выборки я пытаюсь решить следующим образом (нашел на одном из этих кодирующих участков: codercharts, codeeval и т.д.):

Проблема заключается в следующем: выберите номер, переверните его цифры и добавьте их в оригинал. Если сумма не является палиндром (это означает, что это не то же самое число слева направо и справа налево), повторите эту процедуру.

Супер простой, не так ли? Простой пока хватит, но я не знаю, как генерировать числа до тех пор, пока не будет выполнено определенное условие. Я проверил itertools.takeWhile и itertools.dropWhile, но они работают с существующими списками, которые мне все равно придется создавать.

Я пробовал генераторы, которые работают, но я не знаю, как сжать их в одной строке.

Argh, в Haskell, создающем бесконечный список, а затем с использованием takeWhile, но в Python я застрял. Будем очень благодарны за любые указатели в правильном направлении.

Редактировать: Чтобы быть более кратким, я пытаюсь сделать это на одной строке (за вычетом импорта, конечно).

+5

Это питон вопрос или вопрос Haskell? И что это * вопрос, точно? – crockeea

+2

«Арг, в Haskell, создающем бесконечный список, а затем с использованием takeWhile, но в Python я застрял» - я думаю, она хочет Python! – Dayan

+0

Может быть, рекурсивная лямбда-функция? –

ответ

4

Я бы начать с написанием этого рекурсивным образом:

def frob(x): 
    if str(x) == str(x)[::-1]: 
     return x 
    else: 
     return frob(x + int(str(x)[::-1])) 

print frob(29) 

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

def frob(f, x): 
    if str(x) == str(x)[::-1]: 
     return x 
    else: 
     return f(f, x + int(str(x)[::-1])) 

print frob(frob, 29) 

Это позволяет писать frob как однострочника.

def frob(f, x): 
    return x if str(x) == str(x)[::-1] else f(f, x + int(str(x)[::-1])) 

print frob(frob, 29) 

Который может быть превращен в лямбда-функцию.

frob = lambda f, x: x if str(x) == str(x)[::-1] else f(f, x + int(str(x)[::-1])) 

print frob(frob, 29) 

Вы можете использовать fixed point combinator изменить подпись функции, так что она больше не требует, чтобы передать себя в явном виде.

frob = (lambda f: lambda x: f(f,x))(lambda f, x: x if str(x) == str(x)[::-1] else f(f, x + int(str(x)[::-1]))) 
print frob(29) 

На данный момент вам больше не требуется назначение, и вы можете вызвать лямбду в одной строке.

print (lambda f: lambda x: f(f,x))(lambda f, x: x if str(x) == str(x)[::-1] else f(f, x + int(str(x)[::-1])))(29) 

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

def troz(x): 
    return frob(x + int(str(x)[::-1])) 

Который сводится к:

print (lambda x: (lambda f: lambda x: f(f,x))(lambda f, x: x if str(x) == str(x)[::-1] else f(f, x + int(str(x)[::-1])))(x + int(str(x)[::-1])))(29) 
+0

Святой. Щелчок. Это прекрасно. Я никогда не работал с компиляторами с фиксированной точкой, но теперь я определенно заинтересован! – Aeveus

+0

Другим подходом было бы использование 'accumulate', например. 'next (dropwhile (lambda x: str (x)! = str (x) [:: - 1], накапливается (repeat (z + int (str (z) [:: - 1])), lambda x, _ : x + int (str (x) [:: - 1])))) '. Но в этом нет никакого смысла, поскольку он значительно уступает простой петле. – DSM

+0

"* Тогда, поскольку лямбда не может ссылаться на себя по имени *« Я думаю, что это работает (пожалуйста, поправьте меня, если я ошибаюсь): f = lambda x: 1 + f (x). По определению он перестает быть лямбда-функцией, но вы можете записать его в одной строке. –

Смежные вопросы