Pythonにおける変数の付与"="の問題

5231 ワード

pythonにおける変数付与問題については,この文章はよく述べている.https://www.jianshu.com/p/521bdd67790e
特に、pythonはデータに対して、C言語はメモリに対して
前に書く
pythonの「変数」は、値を割り当てることができる一般化されたオブジェクトであり、より正確には「参照」であり、単なるラベルであり、メモリ内の実際のオブジェクト(狭義のオブジェクト)に関連付けて、このラベルを操作することによって実际のオブジェクトを操作する役割を果たす.
1つの変数は孤立して存在することはできません.作成時には、変数のタイプ、メモリアドレス、値がオブジェクトのタイプ、メモリアドレス、値を指すメモリ内の実際のオブジェクトに指向する必要があります.
1つの変数自体はいずれのデータ型にも属しず、pythonは1つの変数にメモリを割り当てることはなく、同じ変数は異なるタイプのオブジェクト(例a=300、a='a'、a=[300,'a'])を指すことができる.
Pythonは参照カウントメカニズムによって自動ゴミ回収機能を実現し、Pythonメモリの各オブジェクトには参照カウンタがあり、そのオブジェクトがどの変数で参照されているかを統計するために使用されます.1回の参照、カウントが1回、1回の参照が少なく、カウントが1回少ない.カウントがゼロの場合、Pythonはオブジェクトを破棄し、メモリを回収します.
割り当て操作は、表面的には「=」の右の量の値を左の変数に割り当てますが、本質的には右の量に対応するメモリオブジェクトを左の変数に関連付けるプロセスです.次の例を参照してください.
>>>a = 300

この付与文は3つのことをした:1)メモリを開いた(id(a)でアドレスを表示できる).2)当該メモリの値を300とする.3)変数aをメモリに向ける.aが他のオブジェクトに再び指し示す前に、aはメモリを指し示し、すなわち整数300を表す.ここでメモリの中の300は狭義の「対象」であり、実在するものである.
付与文では、通常、2つのケースがあります.1つは、「変数=オブジェクト」、例えばa=300、a='python cgx'、a=[1,2,3]、a=(1,2,3)などの狭義のオブジェクトを変数に付与することです.これらの付与文の右側は、メモリに実在するオブジェクトであり、メモリに存在します.もう1つは、「変数=変数」などの変数に変数を割り当てることです.例えば、b=a、右側にはすでに存在する変数があります.参照であり、ラベルであり、特定のオブジェクトではありませんが、実際のオブジェクトを指しているに違いありません.そうしないと、aは保存できません.この2つのケースはpythonで大きく異なり,以下ではそれぞれ詳細に議論する.
(一)変数=オブジェクト、オブジェクトが変数に付与された場合
この形式についても、2つの状況に分けて議論します.
(1)割り当ての場合、割り当て対象のオブジェクトはメモリに存在しません
この場合、メモリを開き、メモリに対応する値を指定し、変数に関連付ける3つのステップに従います.次のようになります.
>>>a = 300 #int
>>>b = 'python cgx' #string
>>>c = [1,2,3] #list
>>>d = (1,2,3) #tuple
>>>e = {'age':25} #  

(2)値を割り当てる場合、同じ値の「オブジェクト」がメモリに少なくとも1つ存在する
このような状況については、特定のデータ型に基づいて個別に議論する必要があります.
1)int,整型
>>>a = 1 
>>>b = 1
>>>id(a) #1598778384
>>>id(b) #1598778384

上記の例では、aおよびbの指向するメモリアドレスはいずれも15988778384であり、b=1を実行する際にメモリを再開するのではなく、変数bも既存のオブジェクト1に指向することを示す.しかし、すべてのint状況が同じだとは思わないでください.例えば、
>>>a = 300 
>>>b = 300
>>>id(a) #96391536
>>>id(b) #96391664

前の例の経験によれば、ここでaとbの2つの変数はいずれもオブジェクト300を指しているので、id(a)とid(b)は同じであるべきであるが、実際には両者は異なる.これはどのような状況であるか.いったいどんな整数が同じで、どんな整数が違うのでしょうか.この問題を解決するために、私たちは以下の実験を行います.
>>>for i in range(-1000,1000):
          a = i #   i  a
          b = int(i.__str__()) #  i          int,         i  b
         if a is b: #  a b       
                print(i)
-5
-4
-3
……
255
256

上記のコードの目的は、メモリを共有する整数を表示することです.結果から、-5から256までの262個の整数がメモリを共有することがわかります.これは本当に不思議な存在で、特になぜ負の整数が-5にしかならないのか.この問題はしばらく深く究明しない.pythonがこのようにするのは、これらの小さな整数がプログラミング時に発生する頻度が非常に高いため、破棄生成破棄を絶えず生成すると計算効率が低下し、この操作を減らすために、いっそすべての小さな整数を繰り返し作成する場合を同じ既存の小さな整数に指し、もう一つの変数がこの小さな整数に接続されている限り、彼は破壊されない.またintデータは可変オブジェクトであるため、この小さな整数はメモリに作成されると、変数が彼を指さすまで破棄されません.浮動小数点数ではこのような状況は存在しません.
2)string,文字列型
文字列の場合はintと少し似ていますが、短い文字列(スペースなし)と空の文字列(')では共有メモリです.長い文字列(スペース付き)では、メモリは共有されません.
>>>a = '' #    
>>>b = ''
>>>id(a) #3504816
>>>id(b) #3504816

>>>a = 'sssssssssssssssssssssssssssssssss' #   ,    
>>>b = 'sssssssssssssssssssssssssssssssss' 
>>>id(a) #96397424
>>>id(b) #96397424

>>>a = 's s' #   ,    
>>>b = 's s' 
>>>id(a) #96387624
>>>id(b) #96388856

3)リスト
リストの場合、新しいメモリを毎回開き、空のリスト[]を含む新しいオブジェクトを生成するのは簡単です.次のようになります.
>>>a = [] #   
>>>b = []
>>>id(a) #96384072
>>>id(b) #96384264

>>>a = [1] #   
>>>b = [1]
>>>id(a) #41856328
>>>id(b) #41877640

>>>a = list(range(10000)) #   
>>>b = list(range(10000))
>>>id(a) #41880840
>>>id(b) #41880904

4)tuple,メタグループ型
メタグループの場合、毎回新しいメモリを開き、新しいオブジェクトを生成します.ただし、空のメタグループ()の場合、メモリは共有されます.次のようになります.
>>>a = () #   
>>>b = ()
>>>id(a) #3342408
>>>id(b) #3342408

>>>a = (1,) #   
>>>b = (1,)
>>>id(a) #37476560
>>>id(b) #37702512

>>>a = tuple(range(10000)) #   
>>>b = tuple(range(10000))
>>>id(a) #40619720
>>>id(b) #40699784

4)dict、辞書型
辞書では、新しいメモリを開くたびに、空の辞書{}を含む新しいオブジェクトを生成するのが簡単です.次のようになります.
>>>a = {} #   
>>>b = {}
>>>id(a) #34237752
>>>id(b) #34237824

>>>a = {'x':1} #   
>>>b = {'x':1}
>>>id(a) #5467448
>>>id(b) #5467520

>>>a = dict(enumerate(range(10000))) #   
>>>b = dict(enumerate(range(10000)))
>>>id(a) #41778560
>>>id(b) #41778632

(二)変数B=変数A,変数が変数に付与された場合
変数Aが変数Bに値を付与する場合(変数Aは必ずメモリオブジェクトを指す)、どのデータ型でも複雑で単純であっても、2つの変数が同じメモリユニットを指す結果は1つしかありません.ここではintを用いて例を挙げ,他の場合は後述しない.
>>>a = 1 #    ,-5~256
>>>b = a
>>>id(a) #1598778384
>>>id(b) #1598778384

>>>a = 300 #    
>>>b = a
>>>id(a) #33205968
>>>id(b) #33205968