t
あなたの質問は、値を直接変更するのではなく、ループ内で文字列を構築するときに、文字列を保持するために別の変数を維持する必要がある理由についてのようです。
その理由は、Python の文字列は不変だからです。その文字列の内容を変更できないため、既存の文字列の 2 つの文字の間にスペースを挿入することはできません。必要な変更は、元の文字列の文字のコピーを含む新しい文字列を作成して行う必要があります。
あなたが尋ねてt = t + " " + s[i+1]
いたコード行は、次のことを行います:
- 最初に、 の前の値のコピーを含む新しい文字列を作成
t
し、最後にスペースを連結します。これは一時的な値であり、変数名にバインドされていません。
- 次に、2 番目の新しい文字列が作成され、手順 1 の文字列がコピーさ
s
れ、末尾に文字が連結されます。Python は、ステップ 1 の一時文字列をコピーするのではなく再利用するほど賢いかもしれませんが、これは通常、信頼できるものではありません。
- 最後に、上記の手順 2 で作成された文字列が変数
t
にバインドされ、そこにあった古い文字列が置き換えられます (他の参照がないため、ガベージ コレクションされます)。
提案された代替コードs[i + 1] + " "
は、新しい文字列を作成しますが、それに対して何もしません。何にも割り当てられていないため、すぐにガベージコレクションされます。s[i+1] + " "
が string を変更しないことを理解することが重要s
です。別の構文を使用しようとしても、機能s[i+1] += " "
しないように、この場合は例外が発生します。
これは、コードの少し Pythonic バージョンであり、その機能をより明確にする可能性があります。
def spaced_words(s):
result = s[0] # start with the first letter of the string
for c in s[1:]: # iterate over the rest of the string
result += " " + c # add a space and the next character to the result
return result # when the loop is done, return the result string
for ループは、while ループとコードからの明示的なインデックス付けを置き換えます。これは、従うのがはるかに簡単です。+=
ではなく演算子も使用してresult = result + otherstuff
いますが、これは実際には大きな違いではありません。文字列は不変であるため、result
通常、新しい値が最後に連結されるたびにコピーする必要があります。ただし、CPython (python.org から取得する通常のインタープリター) には、このように文字列に追加するための特別なロジックがいくつかあり、実際には、ほとんどの場合、文字列をコピーすることは回避されます。ただし、これは実装の詳細であり、依存すべきものではありません。
最後に、組み込みstr.join
メソッドを使用して、現在の関数がより簡単かつ効率的に実行することをお勧めします。任意の反復可能なオブジェクトを引数として受け入れ、便利なことに、文字列はその文字に対する反復可能なオブジェクトです。
def spaced_word(s):
return " ".join(s)
それがあなたの質問ではないことは理解していますが、Python の組み込み機能について学ぶことは良いことです。Python は、ほとんどの場合、自分で記述できるコードよりも、必要なことをうまく実行してくれます。