5

何年にもわたって、私が遭遇したさまざまな Python の小片に「ワイルドカード」変数があることに気付きました。Haskell のように機能すると仮定しました: 変数を仮パラメーターで必要な場所に置くことはできますが、バインドはできません。

たとえば、変数の 1 つが必要ない場合に、タプルのアンパック代入の左側でこれを使用しました。

例えば:

_, extension = os.path.splitext(filename)

だから、今日これに似たものを書いたとき:

(lambda (x,_,_): x)((1,2,3))

IE アンダースコアを 2 回バインドしようとしましたが、構文エラーが発生しました。_ が実際の変数であることに驚きました。

(lambda (x,_,z): _)((1,2,3))
> 2

_他のものと同じように、単なる変数名のように見えます。

最初の例のように、好きなように使用できる真のワイルドカード変数はありますか (つまり、タプルのアンパック代入で複数を使用できます)。

4

5 に答える 5

4

Pythonにはワイルドカード変数はありません。

_私はかなり長い間、人々が変数名として使用することを思いとどまらせようとしています。あなたは_ある種の特別な構文と間違えた最初の人ではないので、_この種の混乱を避けるために変数名として使用しない方が良いでしょう。使い捨て変数名として使用する「規則」があった場合_、この規則は誤った方向に進んでいました。

それが引き起こす混乱だけでなく、もっと多くの問題があります。たとえば、インタラクティブインタプリタおよび一般的なgettextエイリアスでと_衝突します。_

式に関しては、最初の引数を除くすべての引数を無視するためにlambda使用します。lambda x, *args: ...それ以外の場合は、のように、使用したくないことを明示的に示す名前を使用しますdummy。sのループの場合range()、私は通常、を使用for i in range(n)し、単に使用しませんi

編集:引数リストでタプルアンパックを使用していることに気づきました(他の回答を見て)のでlambda x, *args: ...、問題は解決しません。パラメータリストでのタプルの解凍は、機能がわかりにくいと見なされたため、Python3.xで削除されました。代わりに、mipadiの答えを使用することをお勧めします。

于 2011-11-01T16:16:49.030 に答える
3

いいえ、PythonにはHaskellに相当するものはありません_。Pythonの規則では_、「使い捨て」変数に使用しますが、これは実際の変数名であり、ご存知のように、同じコンテキストで2回使用することはできません(ラムダパラメーターリストなど)。

あなたが与えた例では、私は単に索引付けを使用します:

lambda tup: tup[0]

また

lambda tup: tup[1]

それほどきれいではありませんが、それを行うためのより良い方法の1つです。

于 2011-11-01T16:12:33.097 に答える
3

あまり。Python は Haskell ではありません。map、apply、reduce、および lambda は一種の二流市民ですが、itertools にはいくつかの興味深い機能があります。

1 行のラムダを使用する必要がない限り、正しい方法は次のとおりです。

def f(x, *args, **kwargs):
    return x

この*args引数では、任意の数の名前のない引数を使用できます (これは、 というタプルとして使用できますargs)。追加の名前付き引数は、 という辞書に含まれkwargsます。

ラムダでこれを行う方法はないと思いますが、通常は必要ありません。関数宣言はどこにでも行くことができます。関数定義を別の関数 (またはループ) 内に置くと、面白い/悪いことをすることに注意してください。

def make_func(s):
    def f(*trash, **more_trash):
        print s
    return f

f1 = make_func('hello')
f2 = make_func('world')
f1(1,2,'ham','spam')
f2(1,2,a=1,b=2)

出力します:

>>> hello
>>> world

@rplnt が指摘したように、これは for ループとは異なります。

funcs = []
for s in ('hello','world'):
    def f():
        print s
    funcs.append(f)

for f in funcs:
    f()

出力します:

>>> world
>>> world

ループには名前空間が 1 つしかないためです。

于 2011-11-01T16:14:54.647 に答える
2

ちょっとしたトリックで可能です:

class _: 
    def __eq__(x,y): return true
_=_() #always create a new _ instance if used, the class name itself is not needed anymore

[(a,b) for (a,_,_,b) in [(1,2,3,4),(5,6,7,8)]]

与える

[(1, 4), (5, 8)] 

Python の Haskells の美しさの一部である、コードをよりエレガントにするため、私はこれを頻繁に使用しています。

于 2013-01-14T20:44:35.893 に答える
1

簡単な答えはノーです。あなたの既存の慣習に従うことができます。あれは

(lambda (x, _1, _2): x)((1,2,3))
于 2011-11-01T16:14:06.597 に答える