25

私がこのコードを書くとき:

polly = "alive"
palin = ["parrot", polly]
print(palin)
polly = "dead"
print(palin)

私はそれがこれを出力すると思った:

"['parrot', 'alive']"
"['parrot', 'dead']"

ただし、そうではありません。それを出力するにはどうすればよいですか?

4

6 に答える 6

57

Python変数はへの参照を保持します。したがって、palinリストを定義するときpollyは、変数自体ではなく、によって参照される値を渡します。

値をバルーンとして想像する必要があります。変数はそれらのバルーンに関連付けられたスレッドです。"alive"はバルーンでpollyあり、そのバルーンへの単なるスレッドであり、palinリストには同じバルーンに関連付けられた別のスレッドがあります。Pythonでは、リストは単純に一連のスレッドであり、すべて0から始まる番号が付けられています。

次に行うことは、polly文字列を新しいバルーン"dead"に結び付けることですが、リストはバルーンに結び付けられた古いスレッドを保持しています"alive"

"alive"各スレッドを参照するようにリストをインデックスで再割り当てすることにより、そのスレッドをリストによって保持されているスレッドに置き換えることができます。あなたの例では、それはスレッド1です:

>>> palin[1] = polly
>>> palin
['parrot', 'dead']

ここでは、palin[1]スレッドを同じものに結び付けただけpollyです。

、、、などdictのPythonのコレクションも、単なるスレッドのコレクションであることに注意してください。これらのいくつかは、リストやdictなど、スレッドを別のスレッドに交換することができます。これにより、Pythonの何かが「可変」になります。settuple

一方、文字列は変更できません"dead"またはのような文字列を定義すると"alive"、それは1つのバルーンになります。スレッド(変数、リストなど)で結び付けることはできますが、その中の文字を置き換えることはできません。そのスレッドを完全に新しい文字列に結び付けることしかできません。

Pythonのほとんどのものは、風船のように機能します。整数、文字列、リスト、関数、インスタンス、クラス、すべてを変数に関連付けることも、コンテナーに関連付けることもできます。

Python名に関するNedBatchelderの論文も読むことをお勧めします。

于 2012-08-22T20:09:19.717 に答える
4

2番目のprintステートメントの前に、新しい値を次の場所に保存しますpalin

palin = ["parrot", polly]
于 2012-08-22T20:04:25.003 に答える
4

文字列をリストに入れると、リストには文字列のコピーが保持されます。文字列が元々変数であったか、リテラル値であったか、関数呼び出しの結果であったか、または他の何かであったかは関係ありません。リストに表示されるまでには、それは単なる文字列値です。後で文字列を生成したものを変更しても、リストに影響はありません。

値が変更されたときに通知される値への参照を保存する場合、通常のメカニズムは、「参照された」値を含むリストを使用することです。これを例に適用すると、ネストされたリストになります。例:

polly = ["alive"]
palin = ["parrot", polly]
print(palin)
polly[0] = "dead"
print(palin)
于 2012-08-22T20:12:55.543 に答える
2

リストには値のみが含まれ、必要に応じて変数への参照は含まれません。ただし、ラムダをリストに格納し、ラムダに変数の値を検索させることはできます。

>>> a = 'a'
>>> list = ['a',lambda: a]
>>> list[1]
<function <lambda> at 0x7feff71dc500>
>>> list[1]()
'a'
>>> a = 'b'
>>> list[1]()
'b'
于 2012-08-22T20:11:41.397 に答える
1

できません。ベアネームへの割り当てはPythonであり、常に名前を再バインドするだけであり、この操作をカスタマイズまたは監視することはできません。

できることはpolly、文字列の代わりに可変オブジェクトを作成し、名前を再バインドする代わりにその値を変更することです。簡単な例:

>>> polly = ['alive']
>>> items = ['parrot', polly]
>>> items
['parrot', ['alive']]
>>> polly[0] = 'dead'
>>> items
['parrot', ['dead']]
于 2012-08-22T20:14:13.023 に答える
0

他の回答は、何がうまくいっているのかを説明しています。

これは、オブジェクトの使用を動機付ける(いくつかの)問題の1つです。たとえば、次のようにします。

class Animal:
    def __init__(self, aniType, name):
        self.aniType = aniType
        self.name = name
        self.isAlive = True

    def kill(self):
        self.isAlive = False

    def getName(self):
        return self.name

    def getType(self):
        return self.aniType

    def isLiving(self):
        return self.isAlive


polly = Animal("parrot", "polly")

print(polly.getName()+' the '+polly.getType()+' is alive?')
print(polly.isLiving())

polly.kill()

print(polly.getName()+' the '+polly.getType()+' is alive?')
print(polly.isLiving())

単純なタスクの場合、最初は多くのコードのように見えるかもしれませんが、オブジェクトはすべてを整理するのに役立つため、このようなことを行うための方法であることがよくあります。

そのプログラムの出力は次のとおりです。

polly the parrot is alive?
True
polly the parrot is alive?
False
于 2012-08-22T20:35:14.610 に答える