なぜ list.join(string) ではなく string.join(list) なのでしょうか?

聞く:

これは私をいつも混乱させました。これはより良いようです:

["Hello", "world"].join("-")

これより:

"-".join(["Hello", "world"])

これには何か特別な理由があるのでしょうか?

HuntsBot で世界的なフリーランスの機会を探る – Huntsbot.com

答え 1:

Huntsbot.com は、10 以上のグローバルなアウトソーシング タスク プラットフォームのアウトソーシング ニーズを集約し、アウトソーシング タスクと機会を簡単かつ効率的に見つけることができるようにします。

これは、任意の反復可能なオブジェクト (リスト、タプル、辞書、セットなど) を結合できるが、その内容と「結合子」は文字列でなければならないためです。

例えば:

'_'.join(['welcome', 'to', 'stack', 'overflow'])
'_'.join(('welcome', 'to', 'stack', 'overflow'))

'welcome_to_stack_overflow'

文字列以外のものを使用すると、次のエラーがスローされます。

TypeError: シーケンス項目 0: 期待される str インスタンス、int が見つかりました

即使在代码上有意义,我在概念上也不同意。 list.join(string) 看起来更像是一种面向对象的方法,而 string.join(list) 对我来说听起来更程序化。

那么为什么不在可迭代对象上实现呢?

@TimeSheep:整数列表没有有意义的连接,即使它是可迭代的。

我尝试使用 print(str.join('-', my_list)) 并且它有效,感觉更好。

@TimeSheep 因为 iterable 不是具体类型,所以 iterable 是一个接口,任何定义 __iter__ 方法的类型。对于非常特殊的用例,要求所有可迭代对象也实现 join 会使通用接口(也涵盖非字符串上的可迭代对象)复杂化。在字符串上定义 join 以“不直观”顺序为代价绕过了这个问题。一个更好的选择可能是让它成为一个函数,第一个参数是可迭代的,第二个(可选的)是连接字符串 - 但那艘船已经航行了。

答え 2:

HuntsBot で世界的なフリーランスの機会を探る – Huntsbot.com

これは、Python-Dev アーカイブの String メソッド...最終スレッドで議論され、Guido によって受け入れられました。このスレッドは 1999 年 6 月に開始され、str.join は 2000 年 9 月にリリースされた Python 1.6 (Unicode サポート付き) に組み込まれました。 Python 2.0 (join を含む str メソッドをサポート) は 2000 年 10 月にリリースされました。

このスレッドでは 4 つのオプションが提案されました: str.join(seq) seq.join(str) seq.reduce(str) 組み込み関数としての join

str.join(seq)

seq.join(str)

seq.reduce(str)

組み込み関数として追加

Guido はリストとタプルだけでなく、すべてのシーケンス/反復可能なオブジェクトをサポートしたいと考えています。

seq.reduce(str) は初心者にとっては難しいです。

seq.join(str) は、シーケンスから str/unicode への予期しない依存関係を導入します。

組み込み関数としての join() は、特定のデータ型のみをサポートします。したがって、組み込みの名前空間を使用するのは適切ではありません。 join() が複数のデータ型をサポートする場合、最適化された実装を作成するのは困難になります。add メソッドを使用して実装すると、 O(n²) になります。

区切り文字列 (sep) は省略しないでください。暗黙的よりも明示的な方が優れています。

以下に追加の考えをいくつか示します(私自身と私の友人の考え)。

Unicode のサポートは予定されていますが、最終的なものではありません。 UTF-8 が UCS2/4 に取って代わる可能性が最も高いのはそのときです。 UTF-8 文字列のバッファーの合計長を計算するには、文字エンコード規則を知っている必要があります。

その時までに、Python はユーザーがシーケンスのような (反復可能な) クラスを作成できる一般的なシーケンス インターフェイス ルールを決定していました。ただし、Python は 2.2 まで拡張組み込み型をサポートしていませんでした。当時、基本的な反復可能なクラスを提供するのは困難でした (別のコメントで述べられています)。

過去のメールに記録されている Guido の決定は、str.join(seq) に関するものでした。

面白いですが、それは正しいようです!さあ、バリー…グイド・ヴァン・ロッセン

很好,这记录了推理。很高兴了解更多关于“从序列到 str/unicode 的意外依赖”。 ——以及是否仍然如此。

这是最好的答案,因为它提供了权威背景和选择它的原因。

答え 3:

優秀なフリーランサーには、ニーズに敏感でニーズを正確に捉える能力が求められます。huntsbot.com はその機会を提供します。

join() メソッドがリスト クラスではなく文字列クラスにあるからでしょうか?

これは面白そうだと同意します。

http://www.faqs.org/docs/diveintopython/odbchelper_join.html を参照してください。

歴史的メモ。私が初めて Python を学んだとき、join はデリミタをパラメータとして受け取るリストのメソッドであると予想していました。多くの人が同じように感じていますが、結合方法には裏話があります。 Python 1.6 より前は、文字列にはこれらすべての便利なメソッドがありませんでした。すべての文字列関数を含む別の文字列モジュールがあり、各関数は最初の引数として文字列を受け取ります。これらの関数は、文字列自体に配置するのに十分重要であると考えられており、Lower、Upper、Split などの関数には意味があります。しかし、多くのコア Python プログラマは、新しい join メソッドに反対し、これはリスト上のメソッドであるべきだと主張したり、まったく移動すべきではなく、古い文字列モジュールの一部のままにしておくべきだと主張しています (これにはまだ多くの便利な機能があります)中に物が入っています)。ここでは新しい join メソッドを使用しているだけですが、どちらの方法でもコードが記述されていることがわかります。それが本当に気になる場合は、代わりに古い string.join 関数を使用できます。 — Mark Pilgrim、Python の詳細

Python 3 string 库已删除所有多余的 str 方法,因此您不能再使用 string.join()。就个人而言,我从不认为它“有趣”,它非常有意义,因为您可以加入的不仅仅是列表,但加入者始终是一个字符串!

答え 4:

Huntsbot.com は、10 以上のグローバルなアウトソーシング タスク プラットフォームのアウトソーシング ニーズを集約し、アウトソーシング タスクと機会を簡単かつ効率的に見つけることができるようにします。

最初は直感に反すると思いますが、これには十分な理由があります。次の理由により、Join をリスト メソッドにすることはできません。

さまざまな反復可能オブジェクト (タプル、ジェネレーターなど) に対しても機能する必要があります。

文字列の種類が異なると動作も異なる必要があります。

実際には 2 つの接続方法があります (Python 3.0)。

>>> b"".join

>>> "".join


join がリスト メソッドの場合は、その引数を調べて、どれを呼び出すかを決定する必要があります。また、byte と str を連結することはできないため、現在の方法は理にかなっています。

Huntsbot.com – プログラマーの副業にとって最初の選択肢であり、タスクのアウトソーシング、リモートワーク、クリエイティブな製品の共有とサブスクリプションのためのワンストップ プラットフォームです。

答え 5:

Huntsbot.com は、リモートで働きたいデジタル遊牧民がより正確かつ効率的に互いを見つけられるよう、さまざまな分野をカバーする世界 7 大陸のリモートワークの機会を選択しています。

なぜ list.join(string) ではなく string.join(list) なのでしょうか?

これは、結合が「文字列」メソッドであるためです。任意の反復可能なオブジェクトから文字列を作成します。メソッドをリストに固定する場合、リストではない反復可能オブジェクトがある場合はどうなるでしょうか?

文字列のタプルがある場合はどうなるでしょうか?これがリスト メソッドの場合は、要素を文字列に連結する前に、このような各文字列反復子をリストに変換する必要があります。例えば:

some_strings = ('foo', 'bar', 'baz')

独自のリスト結合メソッドをロールしてみましょう。

class OurList(list): 
    def join(self, s):
        return s.join(self)

これを使用するには、まず各反復可能オブジェクトからリストを作成して文字列を反復可能オブジェクトに連結する必要があり、これによりメモリと処理能力が浪費されることに注意してください。

>>> l = OurList(some_strings) # step 1, create our list
>>> l.join(', ') # step 2, use our list join method!
'foo, bar, baz'

したがって、組み込みの文字列メソッドを使用するだけでなく、リスト メソッドを使用するには追加の手順を追加する必要があることがわかります。

>>> ' | '.join(some_strings) # a single step!
'foo | bar | baz'

発電機のパフォーマンスに関する警告

str.join を使用して最終文字列を作成する Python のアルゴリズムは、実際には反復可能オブジェクトを 2 回渡す必要があるため、ジェネレータ式を指定した場合は、最終文字列を作成する前にそれをリストに実体化する必要があります。

したがって、一般にジェネレーターを渡す方がリスト内包表記よりも優れていますが、str.join は例外です。

>>> import timeit
>>> min(timeit.repeat(lambda: ''.join(str(i) for i in range(10) if i)))
3.839168446022086
>>> min(timeit.repeat(lambda: ''.join([str(i) for i in range(10) if i])))
3.339879313018173

それでも、str.join 操作は意味的には「文字列」操作であるため、別の反復可能オブジェクトではなく str オブジェクトに配置することは依然として意味があります。

答え 6:

Huntsbot.com 世界 7 大陸でリモートワークの機会を提供し、さまざまな働き方を模索

これは、分割の自然な直交操作と考えてください。

これが反復可能なものであれば何でも機能するため、リストに簡単に実装できない理由を理解しています。

読みやすくするために、それを言語で見たいのですが、それは実際には実現可能ではないと思います。反復可能オブジェクトがインターフェースである場合、それをインターフェースに追加できますが、それは単なる慣例です。それを反復可能なもののセットに追加するための中心的な方法はありません。

答え 7:

優秀なフリーランサーには、ニーズに敏感でニーズを正確に捉える能力が求められます。huntsbot.com はその機会を提供します。

.join(my_list) の - は、要素の連結からリストへの変換から文字列への変換を宣言します。それは結果志向です。 (記憶と理解を容易にするためだけに)

参考のために、詳細なmethods_of_stringチートシートを作成しました。

string_methods_44 = {
    
    
    'convert': ['join','split', 'rsplit','splitlines', 'partition', 'rpartition'],
    'edit': ['replace', 'lstrip', 'rstrip', 'strip'],
    'search': ['endswith', 'startswith', 'count', 'index', 'find','rindex', 'rfind',],
    'condition': ['isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isnumeric','isidentifier',
                  'islower','istitle', 'isupper','isprintable', 'isspace', ],
    'text': ['lower', 'upper', 'capitalize', 'title', 'swapcase',
             'center', 'ljust', 'rjust', 'zfill', 'expandtabs','casefold'],
    'encode': ['translate', 'maketrans', 'encode'],
    'format': ['format', 'format_map']}

答え 8:

他社より一歩先を行き、ネットワーク全体 –huntsbot.com が独占的に提供するワンストップのアウトソーシングタスク、リモートワーク、クリエイティブ製品のサブスクリプションサービスをお楽しみください。

主な理由は、someString.join() の結果が文字列であるためです。

シーケンス (リスト、タプルなど) は結果に表示されず、文字列のみが表示されます。結果は文字列なので、文字列メソッドとして意味があります。

回答 9:

HuntsBot Weekly – 成功した製品事例を時々共有し、彼らがどのようにして自身の副業を成功させたかを学びましょう – Huntsbot.com

どちらも見栄えは良くありません。

string.join(xs, delimit) は、string モジュールがリストの存在を認識していることを意味しますが、string モジュールは文字列のみを処理するため、リストの存在は認識していません。

list.join(delimit) の方が優れています。なぜなら、私たちは基本的な型として文字列に慣れているからです (言語的にはそうです)。ただし、これは、結合には動的なディスパッチが必要であることを意味します。a.split("\n") のコンテキストでは、Python コンパイラーは a が何であるかを認識できない可能性があり、次の場合にはそれを検索する必要があります (vtable ルックアップと同様)。費用もかかりますし、時間もかかります。

Python ランタイム コンパイラーが list が組み込みモジュールであることを認識している場合、動的検索をスキップしてインテントを直接バイトコードにエンコードできます。そうでない場合は、「a」の「結合」を動的に解析する必要があり、これにはいくつかのコードが必要となる場合があります。各層 呼び出しの継承 (Python は動的言語であるため、結合の意味は呼び出し間で変わる可能性があります)。

悲しいことに、これは抽象化の究極の欠陥です。どのような抽象化を選択しても、その抽象化は、解決しようとしている問題のコンテキスト内でのみ意味をなすため、それらをつなぎ合わせ始める頃には、決して意味をなさないことになります。自分のイデオロギーと一致するビューでそれらを包み込むのではなく、根底にあるイデオロギーと矛盾しない一貫した抽象化を持っています。これを知っていると、Python のアプローチは、独自のラッパーまたは独自のプリプロセッサを作成することで、より安価で、見た目を「良くする」ためにより多くの費用を支払うことができるという点で、より柔軟です。

“字符串模块知道存在一个列表,它没有业务知道”不是真的。 join() 方法的参数是任何可迭代的,因此 str 不需要了解 list(至少,对于该方法而言)。显然“可迭代”比 str 更基本,因为 str 实际上本身就是可迭代的! (另外,我认为 list 比 str 更基本,因为 Unicode 字符处理比存储一系列对象要复杂得多,但正如我所说的,它在这里无关紧要。)

“如果python运行时编译器知道列表是一个内置模块,它可以跳过动态查找”(你的意思是“类”而不是“模块”。)这很奇怪。如果 l 是一个列表,而 s 是一个字符串,那么 l.join(s) 和 s.join(l) 都涉及使用类系统进行动态查找。也许如果您使用字符串文字 "-".join(...) 它可以避免它,但这也适用于列表文字 [...].join("-")。我想也许前者更常见。但我认为无论如何都没有完成这种优化,而且正如 Yoshiki 的回答所示,这当然不是决定的原因。

答え 10:

Huntsbot.com は効率的に収益を上げ、10 を超えるタスク プラットフォームのアウトソーシング ニーズに対してワンストップのフォローアップを提供します

変数 my_list と "-" は両方ともオブジェクトです。具体的には、これらはそれぞれ list クラスと str クラスのインスタンスです。 join関数はstrクラスに属します。したがって、オブジェクト「-」は入力として my_list を受け取るため、構文「-」.join(my_list) が使用されます。

回答 11:

優秀なフリーランサーには、ニーズに敏感でニーズを正確に捉える能力が求められます。huntsbot.com はその機会を提供します。

リストとタプルを単に結合することはできません。ほぼすべての反復可能オブジェクトを追加できます。反復可能なオブジェクトには、ジェネレーター、マップ、フィルターなどが含まれます。

>>> '-'.join(chr(x) for x in range(48, 55))
'0-1-2-3-4-5-6'

>>> '-'.join(map(str, (1, 10, 100)))
'1-10-100'

ジェネレーター、マップ、フィルターなどを使用する利点は、メモリ消費が非常に少なく、ほぼ瞬時に作成されることです。

概念的には、これは単なる別の理由です。

str.join()

この能力は str に付与する場合のみ有効です。すべてのイテレーターへの接続を許可する代わりに、リスト、タプル、セット、ディクショナリ、ジェネレーター、マップ、フィルターはすべて、共通の親としてオブジェクトのみを持ちます。

もちろん、 range() と zip() もイテレータですが、str を返すことがないため、str.join() と一緒に使用することはできません。

>>> '-'.join(range(48, 55))
Traceback (most recent call last):
  File "", line 1, in 
TypeError: sequence item 0: expected str instance, int found

“而不是向所有迭代器授予连接:[...],所有这些迭代器都只有对象作为公共父级。”——这似乎是一个合理的理由(没有 iter.join())

翻訳链接:https://www.huntsbot.com/qa/VdRV/why-is-it-string-joinlist-instead-of-list-joinstring?lang =zh_CN&from=csdn

Huntsbot.com は、10 以上のグローバルなアウトソーシング タスク プラットフォームのアウトソーシング ニーズを集約し、アウトソーシング タスクと機会を簡単かつ効率的に見つけることができるようにします。

おすすめ

転載: blog.csdn.net/kalman2019/article/details/128692830