1

文字列変数の割り当てが次のようになるPythonコードを見ました。

var1 = var2[:]

次の違いは何ですか?

var1 = var2

これが私の実験です:

>>> original = "some text"
>>> copy1 = original
>>> copy2 = original[:]
>>> original = "another text"
>>> copy1
'some text'
>>> copy2
'some text'

更新しました:

ここに完全なコードがあります。このコードは、置換暗号のキーを検索します。「[:]」を削除すると、このコードの動作が非常に遅くなります。

4

5 に答える 5

5

interningにより、多くの場合、(結果のオブジェクトに) 両者の間に違いはありません。演算子を使用して、2 つの変数が同じオブジェクトを指しているかどうかを確認できます。これは、オブジェクトの実際のメモリ アドレスが同じかどうかを確認するis演算子とは対照的です。==

>>> a = "foo"
>>> b = a
>>> a is b
True
>>> c = a[:]
>>> a is c
True

インターンは、メモリを節約し、不変オブジェクトの比較を高速化するためのメカニズムであり、次のように機能します。新しい不変オブジェクトを作成する前に、python は同一の不変オブジェクトが既に存在するかどうかを確認します。その場合、既存のオブジェクトへの参照を使用するだけです。不変を変更する方法がないため、害を及ぼすことなくそれを行うことができます。これが、独立して作成された 2 つの文字列でさえ、同じオブジェクトを指している可能性がある理由です。

>>> a = "foo"
>>> b = "foo"
>>> a is b
True

しかしvar2、 のような可変シーケンシャル オブジェクトである場合、listvar2[:]の浅いコピーにvar2なるため、一方を変更しても他方には影響しません。

>>> a = list("foo")
>>> a
['f', 'o', 'o']
>>> b = a
>>> b is a
True
>>> c = a[:]
>>> c is a
False
>>> b.pop()
'o'
>>> a
['f', 'o']
>>> b
['f', 'o']
>>> c
['f', 'o', 'o']

全体像については、Ashwini Chaudharys の回答もお読みください。

于 2012-11-06T08:20:30.850 に答える
2

[:] 表記はスライスに使用されますが、

a[m:n]インデックスからからmまでn-1の文字を返します。何も渡されない場合は、文字列全体を返します。

In [1]: a="foobar"

In [2]: a[:]          #this is equal to a only as nothing to passed to slicing
Out[2]: 'foobar'

In [3]: a[1:]         #return everything after index 1
Out[3]: 'oobar'

In [4]: a[:1]         #return everything before 1st index
Out[4]: 'f'

In [5]: a[:-1]        #return everything before the last character
Out[5]: 'fooba'

b=a[:]との違いb=aは、b=aが内部で実行するステップ数が少ないことです。

In [7]: def func1():
   ...:     a="foo"
   ...:     b=a
   ...:     

In [8]: def func2():
   ...:     a="foo"
   ...:     b=a[:]
   ...:     

In [9]: dis.dis(func1)
  2           0 LOAD_CONST               1 ('foo')
              3 STORE_FAST               0 (a)

  3           6 LOAD_FAST                0 (a)
              9 STORE_FAST               1 (b)
             12 LOAD_CONST               0 (None)
             15 RETURN_VALUE        

In [10]: dis.dis(func2)
  2           0 LOAD_CONST               1 ('foo')
              3 STORE_FAST               0 (a)

  3           6 LOAD_FAST                0 (a)
              9 SLICE+0             
             10 STORE_FAST               1 (b)
             13 LOAD_CONST               0 (None)
             16 RETURN_VALUE 

timeit

In [11]: %timeit func1()
1000000 loops, best of 3: 336 ns per loop

In [12]: %timeit func2()
1000000 loops, best of 3: 397 ns per loop
于 2012-11-06T08:21:53.410 に答える
1

listコードでは、変数を文字列ではなく、変数にすることができることに注意してください。

次の例を参照してください。

>>> a = [1,2,3]
>>> b = a
>>> b[0] = 'foo'
>>> a
['foo', 2, 3]

しかし:

>>> a = [1,2,3]
>>> b = a[:]
>>> b[0] = 'foo'
>>> a
[1, 2, 3]

つまり、最初の例では、 への参照aが保持されb、変更bが変更されますa。スライス表記[:]を使用すると、代わりにディープ (1 レベル) コピーが作成されます。

于 2012-11-06T08:26:00.477 に答える
1

originalリンク先の完全なコードでは、listではなくである可能性がありますstr

parentkey,parentscore = startkey or list('ABCDEFGHIJKLMNOPQRSTUVWXYZ'),-99e99

その後

child = parentkey[:]
# swap two characters in the child
child[a],child[b] = child[b],child[a]

lazyrで述べたように、この場合、コピーを作成すると違いが生じます。

于 2012-11-06T08:24:47.370 に答える
0

a[:]、 と同じなのでaid(a) == id(a[:])違いはありません)

a = 'Convert an integer number to a binary string Convert an integer number to a binary'
id(a) == id(a[:])
>>> True

リスト [:] の場合、そのコピーを返します。

a = [1, 2, 3]
id(a) == id(a[:])
>>> False
于 2012-11-06T08:24:39.847 に答える