Help us understand the problem. What is going on with this article?

def文及びlambda式不使用で関数を作る挑戦

More than 1 year has passed since last update.

はじめに

初心者プログラマーながらアウトプットにも挑戦してみようと思い記事を書くことにしました。

※以下の記事で使用している内包表記内でのyield式の使用は3.7で非推奨、3.8以降で動かないことが判明しています。参照

環境

• python3.6.1

TL;DR

位置引数を受けるものなら標準ライブラリの使用まで妥協し実現できた。
キーワード引数の受け取り方は不明

詳細

この試みを思い立ったきっかけは何処かでyieldを式として使えるという記事を見たことです。
と言うわけで位置引数一つを取る事が可能になりました。

next(
    func for func in (
        (
            0 for _args, _return in iter([[], [None]].copy,None)
            if _args.append((yield _return[0])) or [[
                0 for arg in _args 
                for _return[0] in (arg,) if not print('arg is', arg)
            ]] and _args.clear()
        ),
    ) if [next(func)]
).send

次に必要なのは複数の引数をどうにかしてこれに渡す事です。
max/min関数が誂え向きでした。と言う訳で複数の位置引数を取れるようになります。
functool.partialで小細工をして、

next(
    __import__('functools').partial(
        max, _return,
        key = next(
            func for func in ((
                0
                for _ in iter(int,1)
                if _args.append((yield 0)) or 
                ((_return.__setitem__(0,None) or [[
                    0 for _return, *args in (_args,)
                    for _return[0] in (args,) if not print('args are', args)
                ]] and _args.clear())
                if ((_args[0] is _return and _args.count(_return)==1 or _args.clear()) and len(_args)==_count) else _return.__setitem__(0,'error'))
            ),) if [next(func)]
        ).send
    )
    for _return, _count, _args in ((['error'], 1+2, []),)
)

以下のコードはこれらを利用し、再帰処理的に階差計算をするものです。
そのままやると、動かしている最中のジェネレーターにsendは送れないと怒られるので毎度生成される様にしてあります。

next(func for func in ((0 for _args, _return in iter([[], [None]].copy,None)if _args.append((yield _return[0])) or [[0 for N in _args for _return[0] in (next(func for func in ((0 for _args, _return in iter([[], [None]].copy,None)if _args.append((yield _return[0])) or [[0 for f in _args for _return[0] in (f()(f, N)[0],)]] and _args.clear()),) if [next(func)]).send((next(__import__('functools').partial(max, _return,key = next(func for func in ((0for _ in iter(int,1)if _args.append((yield 0)) or ((_return.__setitem__(0,None) or [[0 for _return, f, n in (_args,)for _return[0] in (1 if n==1 else f()(f, n-1)[0]*n,)]] and _args.clear())if ((_args[0] is _return and _args.count(_return)==1 or _args.clear()) and len(_args)==_count) else _return.__setitem__(0,'error'))),) if [next(func)]).send)for _return, _count, _args in ((['error'], 1+2, []),)) for _ in range(N)).__next__),) ]] and _args.clear()),) if [next(func)]).send

階乗といえば個人的にはreduce(int.__mul__, range(1,6))ってするのが好きです

まとめ

def文又はlambda式アレルギーのあるお子様のいるご家庭でもpythonは安心してお使いいただけます。
難しい事がわからなくともワンライナーはパズルとして気軽に挑戦し、楽しめるので暇つぶしに最適です。

watosar
Pythonをやっています。 iOSアプリ Pythonista は素晴らしいものです。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away