3

私は常に str.join() 引数をリストにラップしています。

'.'.join([str_one, str_two])

追加のリスト ラッパーは、私には常に不必要に思えます。やりたい...

'.'.join(str_one, str_two, str_three, ...)

...またはリストがある場合...

'.'.join(*list_of_strings)

はい、私はミニマリストです、はい、私は好き嫌いがありますが、ほとんどの場合、ここの歴史について、または何かが欠けているかどうかに興味があります. たぶん、スプラットの前に時間がありましたか?

編集:

max() は両方のバージョンを処理することに注意してください。

max(iterable[, key]) max(arg1, arg2, *args[, key])

4

3 に答える 3

4

短いリストの場合、これは問題ではなく、入力するのに正確に2文字かかります。しかし、(私が思うに)最も一般的なユースケースstr.join()は次のとおりです。

''.join(process(x) for x in some_input) 
# or
result = []
for x in some_input:
    result.append(process(x))
''.join(result)

ここで、input_dataには数千のエントリを含めることができ、出力文字列を効率的に生成したいだけです。

反復可能ではなく、受け入れられた可変引数を結合する場合、これは次のように綴る必要があります。

''.join(*(process(x) for x in some_input))
# or
''.join(*result)

これは(おそらく長い)タプルを作成し、それをとして渡すだけ*argsです。

つまり、短い場合は2文字であるのに対し、大きなデータの場合は無駄になります。

履歴メモ

(2番目の編集:すべてのリリースから欠落しているリリースを含むHISTORYファイルに基づいています。Donに感謝します。)

in関数の*args定義はずっと前にPythonで追加されました:

==>リリース0.9.8(1993年1月9日)<==

ケース(a)は、可変長の引数リストに対応するために必要でした。現在、明示的な「varargs」機能があります(最後の引数の前に「*」を付けます)。ケース(b)は、古いクラス定義との互換性のために必要でした。リリース0.9.4までは、複数の引数を持つメソッドを "def meth(self、(arg1、arg2、...))として宣言する必要がありました。 。」。

このような関数にリストを渡す適切な方法は、組み込み関数を使用することでしたapply(callable, sequence)(これは、バージョン1.4のドキュメントで**kwargs最初に見られるものについては言及していません)。

構文を使用して関数を呼び出す機能は*、1.6のリリースノートで最初に説明されています。

apply()関数の代わりに使用できる特別な構文があります。f(* args、** kwds)はapply(f、args、kwds)と同等です。バリエーションf(a1、a2、* args、** kwds)を使用することもでき、f(args)、f( * kwds)のいずれかを除外することもできます。

しかし、バージョン2.2までは文法ドキュメントにはありません。

2.0以前str.join()は存在すらしていなかったので、そうしなければなりませんでしたfrom string import join

于 2012-11-09T21:35:32.027 に答える
2

そのためには、独自の関数を作成する必要があります。

>>> def my_join(separator, *args):
        return separator.join(args)

>>> my_join('.', '1', '2', '3')
'1.2.3'

これは余分なオブジェクトの作成を回避するものではなく、余分なオブジェクトが作成されていることを隠すだけであることに注意してください。args のタイプを調べると、それがtuple.

関数を作成したくなく、文字列の固定リストがある場合は、join の代わりに format を使用できます。

'{}.{}.{}.{}'.format(str_one, str_two, str_three, str_four)

に固執する方が良い'.'.join((a, b, c))です。

于 2012-11-09T21:21:02.830 に答える
2

うーん、これは難しい質問です!どちらのスタイルがよりミニマリストであるかを議論してみてください... すべては慣習に関するものなので、主観的になりすぎずに良い答えを出すことは困難です.

問題は次のとおりです。順序付けられたコレクションを受け入れる関数があります。単一の引数または可変長の引数リストとして受け入れる必要がありますか?


Python は通常次のように答えます。本当に理由がある場合はVLAL。Python ライブラリがこれをどのように反映しているか見てみましょう:

標準ライブラリには、VLAL の例がいくつかあります。

  • またはまたはのように、任意の数の個別のシーケンスで関数を呼び出すことができる場合、zipmapitertools.chain
  • 渡すシーケンスが 1 つあるが、呼び出し元がそのシーケンス全体を単一の変数として持つことを実際には期待していない場合。これは合いそうstr.formatです。

そして、単一の引数を使用する一般的なケース:

  • 単一のシーケンスで一般的なデータ処理を行いたい場合。これは、機能トリオ ( map*、reduce、 ) と、またはfilterのような特殊なスポーンに適合します。のようなステートフルな変換も。 sumstr.joinenumerate
    • パターンは、「interable を消費し、別の iterable を与える」または「iterable を消費し、結果を与える」です。

これがあなたの質問に答えることを願っています。


注:map技術的には var-arg ですが、一般的な使用例は、とmap(func, sequence) -> sequenceで 1 つのバケットに分類されるだけです。reducefilter

*あいまいなケースmap(func, *sequences)は、概念的には - に似ており、 s が var-arg 規則に従うmap(func, izip_longest(sequences))理由は前に説明されました。zip

ここで私の考えに従ってください。結局のところ、すべてはプログラミング スタイルの問題なので、Python のライブラリ関数のいくつかのパターンを指摘しているだけです。

于 2012-11-09T21:43:52.270 に答える