127

私の理解では、Python文字列は不変であるということでした。

次のコードを試しました。

a = "Dog"
b = "eats"
c = "treats"

print a, b, c
# Dog eats treats

print a + " " + b + " " + c
# Dog eats treats

print a
# Dog

a = a + " " + b + " " + c
print a
# Dog eats treats
# !!!

Pythonは割り当てを防ぐべきではありませんか?私はおそらく何かが欠けています。

何か案が?

4

22 に答える 22

209

最初aに文字列「Dog」を指しました。次に、変数aを変更して、新しい文字列「Dogeatstreats」を指すようにしました。文字列「Dog」を実際に変更していません。文字列は不変であり、変数は必要なものを指すことができます。

于 2012-02-01T15:00:03.447 に答える
66

文字列オブジェクト自体は不変です。

a文字列を指す変数、は変更可能です。

検討:

a = "Foo"
# a now points to "Foo"
b = a
# b points to the same "Foo" that a points to
a = a + a
# a points to the new string "FooFoo", but b still points to the old "Foo"

print a
print b
# Outputs:

# FooFoo
# Foo

# Observe that b hasn't changed, even though a has.
于 2012-02-01T14:59:14.960 に答える
52

変数aはオブジェクト「Dog」を指しています。Pythonの変数はタグと考えるのが最善です。a = "dog"タグを別のオブジェクトに移動できます。これは、に変更したときに行ったことですa = "dog eats treats"

ただし、不変性はタグではなくオブジェクトを指します。


にしようとa[1] = 'z'すると、エラーが発生します。"dog""dzg"

TypeError: 'str' object does not support item assignment" 

文字列はアイテムの割り当てをサポートしていないため、不変です。

于 2012-02-01T15:09:06.183 に答える
29

何かは、メモリ位置自体を変更せずにメモリ位置に保持されている値を変更できる場合にのみ変更可能です。

秘訣は次のとおりです。変更の前後のメモリ位置が同じであることがわかった場合、それは変更可能です。

たとえば、リストは変更可能です。どのように?

>> a = ['hello']
>> id(a)
139767295067632

# Now let's modify
#1
>> a[0] = "hello new"
>> a
['hello new']
Now that we have changed "a", let's see the location of a
>> id(a)
139767295067632
so it is the same as before. So we mutated a. So list is mutable.

文字列は不変です。どうやってそれを証明しますか?

> a = "hello"
> a[0]
'h'
# Now let's modify it
> a[0] = 'n'
----------------------------------------------------------------------

我々が得る

TypeError:'str'オブジェクトはアイテムの割り当てをサポートしていません

そのため、文字列の変更に失敗しました。これは、文字列が不変であることを意味します。

再割り当てでは、新しい場所自体を指すように変数を変更します。ここでは、文字列を変更していませんが、変数自体を変更しています。以下はあなたがしていることです。

>> a = "hello"
>> id(a)
139767308749440
>> a ="world"
>> id(a)
139767293625808

id再割り当ての前後は異なるため、これは、実際には変更していないが、変数を新しい場所にポイントしていることを示しています。これはその文字列を変更するのではなく、その変数を変更します。

于 2015-06-27T05:44:14.230 に答える
12

変数は、オブジェクトを指す単なるラベルです。オブジェクトは不変ですが、必要に応じて、ラベルが完全に異なるオブジェクトを指すようにすることができます。

于 2012-02-01T14:59:17.143 に答える
10

検討:

>>> a='asdf'
>>> a.__repr__
<method-wrapper '__repr__' of str object at 0x1091aab90>
>>> a='asdf'
>>> a.__repr__
<method-wrapper '__repr__' of str object at 0x1091aab90>
>>> a='qwer'
>>> a.__repr__
<method-wrapper '__repr__' of str object at 0x109198490>

同じ値を変数に2回格納しても、16進メモリの場所が変更されていないことに注意してください。別の値を保存すると変更されました。文字列は不変です。熱意のためではなく、メモリ内に新しいオブジェクトを作成することによるパフォーマンスの低下を支払うためです。変数aは、そのメモリアドレスを指す単なるラベルです。何でも指すように変更できます。

于 2016-11-20T08:31:53.557 に答える
7

データとそれに関連付けられているラベルには違いがあります。たとえば、あなたがするとき

a = "dog"

データ"dog"が作成され、ラベルの下に配置されaます。ラベルは変更できますが、メモリ内にあるものは変更されません。データ"dog"は、実行後も(ガベージコレクターがデータを削除するまで)メモリに存在します。

a = "cat"

プログラムaでは、^が^を指します"cat"が、文字列"dog"は変更されていません。

于 2012-02-01T15:01:48.963 に答える
7

ステートメントa = a + " " + b + " " + cは、ポインターに基づいて分類できます。

a + " "a変更できないポイントを教えて、現在のワーキングセットに追加する" "と言います。

メモリー:

working_set = "Dog "
a = "Dog" 
b = "eats"
c = "treats"

+ bb変更できないポイントを教えて、現在のワーキングセットに追加すると言います。

メモリー:

working_set = "Dog eats"
a = "Dog" 
b = "eats"
c = "treats"

+ " " + c" "現在のセットに追加すると言います。次に、c変更できないポイントを教えて、現在のワーキングセットに追加します。メモリー:

working_set = "Dog eats treats"
a = "Dog" 
b = "eats"
c = "treats"

最後にa =、結果のセットを指すようにポインタを設定すると言います。

メモリー:

a = "Dog eats treats"
b = "eats"
c = "treats"

"Dog"メモリのチャンクに接続するポインタがなくなるため、が再利用されます。常駐するメモリセクションを変更したことはありません"Dog"。これは、不変の意味です。ただし、メモリのそのセクションを指すラベルがある場合は、それを変更できます。

于 2012-02-01T15:06:17.077 に答える
6
l = [1,2,3]
print id(l)
l.append(4)
print id(l) #object l is the same

a = "dog"
print id(a)
a = "cat"
print id(a) #object a is a new object, previous one is deleted
于 2012-02-01T15:03:41.917 に答える
4

Python文字列は不変です。ただし、aは文字列ではありません。文字列値を持つ変数です。文字列を変更することはできませんが、変数の値を新しい文字列に変更することはできます。

于 2012-02-01T15:00:40.510 に答える
3

Python文字列オブジェクトは不変です。例:

>>> a = 'tanim'
>>> 'Address of a is:{}'.format(id(a))
'Address of a is:64281536'
>>> a = 'ahmed'
>>> 'Address of a is:{}'.format(id(a))
'Address of a is:64281600'

この例では、に別の値を割り当てても変更されないことがわかります。新しいオブジェクトが作成されます。
また、変更することはできません。例:

  >>> a[0] = 'c'
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    **TypeError**: 'str' object does not support item assignment

エラーが発生します。

于 2018-04-06T02:15:44.477 に答える
2

変数は、必要な場所を指すことができます。次の手順を実行すると、エラーがスローされます。

a = "dog"
print a                   #dog
a[1] = "g"                #ERROR!!!!!! STRINGS ARE IMMUTABLE
于 2017-02-17T05:46:01.380 に答える
2

「mutable」は文字列の内容を変更できることを意味し、「immutable」は余分な文字列を追加できないことを意味します。

写真の証明をクリックしてください

于 2018-07-14T13:54:49.857 に答える
1

>>> a = 'dogs'

>>> a.replace('dogs', 'dogs eat treats')

'dogs eat treats'

>>> print a

'dogs'

不変ですね!

変数の変更部分については、すでに説明しました。

于 2015-12-24T10:49:03.037 に答える
1

あなたの例へのこの追加を考慮してください

 a = "Dog"
 b = "eats"
 c = "treats"
 print (a,b,c)
 #Dog eats treats
 d = a + " " + b + " " + c
 print (a)
 #Dog
 print (d)
 #Dog eats treats

私がブログで見つけたより正確な説明の1つは次のとおりです。

Pythonでは、(ほとんど)すべてがオブジェクトです。Pythonで一般的に「変数」と呼ばれるものは、より適切には名前と呼ばれます。同様に、「割り当て」は実際には名前をオブジェクトにバインドすることです。各バインディングには、その可視性を定義するスコープがあります。通常、名前の由来となるブロックです。

例えば:

some_guy = 'Fred'
# ...
some_guy = 'George'

後でsome_guy='George'と言うと、'Fred'を含む文字列オブジェクトは影響を受けません。some_guyという名前のバインディングを変更しました。ただし、「Fred」または「George」の文字列オブジェクトは変更していません。私たちに関する限り、彼らは無期限に生きることができます。

ブログへのリンク:https ://jeffknupp.com/blog/2012/11/13/is-python-callbyvalue-or-callbyreference-nether/

于 2017-04-23T18:03:06.460 に答える
1

上記の回答にもう少し追加します。

id変数の変更は、再割り当て時に変更されます。

>>> a = 'initial_string'
>>> id(a)
139982120425648
>>> a = 'new_string'
>>> id(a)
139982120425776

aこれは、新しい文字列を指すように変数を変更したことを意味します。これで、 2つの string(str)オブジェクトが存在します。

'initial_string'id=139982120425648

'new_string'id=139982120425776

以下のコードを検討してください。

>>> b = 'intitial_string'
>>> id(b)
139982120425648

ここで、bをポイントし、再割り当て前'initial_string'と同じidになります。a

したがって、は'intial_string'変更されていません。

于 2018-03-14T11:52:46.780 に答える
1
a = 'dog'
address = id(a)
print(id(a))

a = a + 'cat'
print(id(a))      #Address changes

import ctypes
ctypes.cast(address, ctypes.py_object).value    #value at old address is intact
于 2020-05-16T13:02:33.237 に答える
0

要約:

a = 3
b = a
a = 3+2
print b
# 5

不変ではありません:

a = 'OOP'
b = a
a = 'p'+a
print b
# OOP

不変:

a = [1,2,3]
b = range(len(a))
for i in range(len(a)):
    b[i] = a[i]+1

不変であるため、これはPython3のエラーです。また、Python 2は明らかに不変ではないため、エラーではありません。

于 2014-10-16T21:00:22.983 に答える
0

組み込み関数id()は、オブジェクトのIDを整数として返します。この整数は通常、メモリ内のオブジェクトの場所に対応します。

\>>a='dog'
\>>print(id(a))

139831803293008

\>>a=a+'cat'
\>>print(id(a))

139831803293120

最初は、「a」は139831803293008のメモリ位置に格納されます。これは、文字列オブジェクトがPythonで不変であるため、参照を変更して再割り当てしようとすると削除され、新しいメモリ位置(139831803293120)へのポインタになります。

于 2019-08-28T10:49:01.650 に答える
-1

2つの文字列値を連結するだけです。(a)の値を変更することはありません。ちょうど今(a)は「dogdog」値を持つ別のメモリブロックを表しています。バックエンドでは、1つの変数が同時に2つのメモリブロックを表すことはないためです。連結前の(a)の値は「犬」でした。しかし、その後(a)は「ドッグドッグ」を表します。これは、現在(a)バックエンド担当者がいるためです。「dogdog」値を持つブロック。そして「犬」は担当者です。(b)によって、(b)が「犬」を表すまで、「犬」はガベージ値としてカウントされません。

混乱は、同じ変数名でバックエンドのメモリブロック(データまたは情報を含む)を表すことです。

于 2020-03-09T12:20:13.017 に答える
-2

numpy配列を不変にして、最初の要素を使用できます。

numpyarrayname[0] = "write once"

それから:

numpyarrayname.setflags(write=False)

また

numpyarrayname.flags.writeable = False
于 2017-07-07T14:32:51.817 に答える
-2

この画像が答えを与えます。読んでください。

ここに画像の説明を入力してください

于 2019-02-12T06:17:08.940 に答える