2016-05-01 8 views
1

私はプログラミングとPython、特にPython3に慣れていません。オンラインチュートリアルを使用して、私は 'ラムダ'の使用法を理解しようとしています。したがって、私は次のコードを書き直し、他の名前付き関数、リストの理解、辞書の理解、またはジェネレータを使用したいと思います。しかし、構文と闘う。私はlambdasを書き換えることができません。匿名関数を書き直すには?

オリジナル機能:

import functools as ft 
import itertools as it 
import os 
import re 
import requests 
import tempfile 
def foo(los, n=None): 
    n = n or len(los) 
    h = it.takewhile(lambda p: p[0] < n, enumerate(los)) 
    s = sorted(h, key=lambda p: p[1]) 
    g = it.groupby(s, lambda p: p[1]) 
    return dict(it.starmap(lambda k, vs: (k, sum(map(lambda i: 1, vs))), g)) 

alist=[1,2,3,1,1,7,8,9,9] 

print(foo(alist)) 

{1: 3, 2: 1, 3: 1, 7: 1, 8: 1, 9: 2} 

マイ調整:

lambda args: expression_with_args 

機能はなります

def smaller_then_ten(e): 
    return e[0] < len(e) 

def foo(los, n=None): 
    n = n or len(los) 
    h = it.takewhile(smaller_then_n, enumerate(los)) 
    s = sorted(h) 
    g = it.groupby(s) 
    return dict(it.starmap(lambda k, vs: (k, sum(map(lambda i: 1, vs))), g)) 

alist=[1,2,3,1,1,7,8,9,9] 

print(foo(alist)) 
+0

Alex Trebekの言葉で、「あなたの応答は質問の形でなければなりません」どうしましたか? – Malvolio

+0

こんにちはMalvolio、私の問題は、私はちょうど異なる機能でラムダを書き換える方法を理解できないということです。 – Mamba

+0

'h = it.takewhile(lambda e:e [0] martineau

答えて

1

あなたは

について...このようにそれを書き換えることができますlike:

def func_name(args): 
    return expression_with_args 

など。

lambda p: p[0] < n 

は次のようになります。

def compare_func(p, n): 
    return p[0] < n 

それはnの値を保存するために少し修正しなければならない唯一の引数を取るkeyための関数としてそれを使用する:

compare_func = ft.partial(compare_func, n=n) 

lambda p: p[1] 

は次のようになります。例えば

def get_first(p): 
    return p[1] 

lambda k, vs: (k, sum(map(lambda i: 1, vs))) 

は次のようになります。最後に

def as_one(i): 
    return 1 

def get_tuple(k, vs): 
    vs_with_ones = map(as_one, vs) 
    vs_sum = sum(vs_with_ones) 
    return (k, vs_sum) 

def foo(los, n=None): 
    n = n or len(los) 
    compare_func = ft.partial(compare_func, n=n) 
    h = it.takewhile(compare_func, enumerate(los)) 
    s = sorted(h, key=get_first) 
    g = it.groupby(s, get_first) 
    return dict(it.starmap(get_tuple, g)) 
+0

こんにちはNikita、ありがとうございました!しかし、get_tuple()では、少なくともコードが実行されていないというエラーがあるようです。とにかくありがとう! – Mamba

+0

@Hiそれを数回更新してみてください。また、 'get_tuple()'は 'as_one()'に依存することに注意してください。私はそれを確認し、それがうまくいった。 'get_tuple(123、(100、200、300、400))'に対して '(123、4)'が得られます。 – Nikita

+0

ニキータに感謝します。しかし、私はまだ 's = sorted(h、key = get_first)を返します。 TypeError:compare_func()missing 1必要な位置引数: 'n'' – Mamba

1

あなたの最初の問題は、単純なタイプミスです。あなたの "より小さい"機能はsmaller_then_tenと定義されましたが、それはsmaller_then_nと呼ばれています。私はここで手足に出て、それをsmaller_than_lenと呼ぶことを意味すると言っています。次に、関数smaller_then_tenは変数nをまったく考慮せず、入力リストの長さだけを使用します。あなたが本当に望むのは、上限を受け取り、リストの最初の要素をチェックする関数を返す関数です。このようなもの。

def smaller_than_len(n): 
    def f(e): 
     return e[0] < n 
    return f 

def foo(los, n=None): 
    n = n or len(los) 
    h = it.takewhile(smaller_than_len(n), enumerate(los)) 
    ... 

あなたの最後の問題は、あなたがsortedgroupby機能からキーの引数を除去したことです。 lambdaを調整に使用したくないと言ったので、それらを "key_func"という名前の新しい関数に置き換えることができます。

def smaller_than_len(n): 
    def f(e): 
     return e[0] < n 
    return f 

def key_func(e): 
    return e[1] 

def foo(los, n=None): 
    n = n or len(los) 
    h = it.takewhile(smaller_than_len(n), enumerate(los)) 
    s = sorted(h, key=key_func) 
    g = it.groupby(s, key=key_func) 
    return dict(it.starmap(lambda k, vs: (k, sum(map(lambda i: 1, vs))), g)) 

これで機能が正しく動作するはずです。

+0

こんにちはクワルツ、あなたの答えに感謝します。あなたの提案を使用して、私は空のセットを取得します。しかし、私は考えを得ると思います。 – Mamba

+0

@Hiそこで、small_than_lenの末尾にreturn文を追加するのを忘れました。今はうまくいくはずです。 – Kwarrtz

0

覚えておくべきことは、特定の環境またはスコープ内で(defまたはを介して)関数が定義されていることです。あなたの関数例では、lambdaはfoo()の内部で定義されており、fooのローカル変数(nなど)にアクセスできます。 smaller_then_tenfooの外に定義されている場合、変数nにアクセスできません。 KwarrtzとNikitaはその問題を解決する方法を示しました。しかし、最も簡単な方法はそうのように、ラムダというところで同じ環境で新しい関数を定義することです:あなたは、Pythonを学んでいると

def foo(los, n=None): 
    def smaller_than_n(tpl): 
     return tpl[0] < n 

    def item1(tpl): 
     return tpl[1] 

    def const1(i): 
     return 1 

    def count(key, values): 
     return key, sum(map(const1, values)) 

    n = n or len(los) 
    h = it.takewhile(smaller_than_n, enumerate(los)) 
    s = sorted(h, key=item1) 
    g = it.groupby(s, key=item1) 
    return dict(it.starmap(count, g)) 

、標準ライブラリに慣れます。それは素晴らしいリソースです。あなたの興味をそそるために、foo()の最初の2行は、itertools.isliceで置き換えられました。item1()は、operator.itemgetterで置き換えられ、fooの全機能はcollections.Counterで置き換えられました。