سؤال

أنا أحيانا ترى قائمة شريحة الجملة المستخدمة في الثعبان رمز مثل هذا:

newList = oldList[:]

بالتأكيد هذا هو مجرد نفس:

newList = oldList

أو أنا في عداد المفقودين شيئا ؟

هل كانت مفيدة؟

المحلول

وكما قلت NXC، بيثون أسماء المتغيرات ويشير في الواقع إلى كائن، وليس بقعة محددة في الذاكرة.

وnewList = oldList من شأنه أن يخلق اثنين من المتغيرات المختلفة التي تشير إلى نفس الكائن، وبالتالي، وتغيير oldList من شأنه أيضا تغيير newList.

ولكن، عند القيام newList = oldList[:]، فإنه "شرائح" القائمة، وإنشاء قائمة جديدة. القيم الافتراضية ل[:] هي 0 ونهاية القائمة، لذلك فإنه ينسخ كل شيء. وبالتالي، فإنه يخلق قائمة جديدة مع جميع البيانات الواردة في أول واحد، ولكن على حد سواء يمكن تغييرها دون تغيير الآخر.

نصائح أخرى

[:] href="http://en.wikipedia.org/wiki/Deep_copy#Shallow_copy" rel="noreferrer"> نسخ الضحلة القائمة، مما يجعل نسخة من بنية قائمة تحتوي على إشارات إلى أعضاء القائمة الأصلي. وهذا يعني أن العمليات على نسخة لا تؤثر على الهيكل الأصلي. ومع ذلك، إذا كنت تفعل شيئا لأعضاء القائمة كلا القائمتين لا تزال تشير إليهم، وبالتالي فإن التحديثات سوف تظهر إذا تم الوصول إلى الأعضاء من خلال الأصلي.

ديب نسخة من شأنه أن تقديم نسخ من جميع أعضاء القائمة أيضا.

ويظهر التعليمات البرمجية المتكررة أدناه نسخة الضحلة في العمل.

# ================================================================
# === ShallowCopy.py =============================================
# ================================================================
#
class Foo:
    def __init__(self, data):
        self._data = data

aa = Foo ('aaa')
bb = Foo ('bbb')

# The initial list has two elements containing 'aaa' and 'bbb'
OldList = [aa,bb]
print OldList[0]._data

# The shallow copy makes a new list pointing to the old elements
NewList = OldList[:]
print NewList[0]._data

# Updating one of the elements through the new list sees the
# change reflected when you access that element through the
# old list.
NewList[0]._data = 'xxx'
print OldList[0]._data

# Updating the new list to point to something new is not reflected
# in the old list.
NewList[0] = Foo ('ccc')
print NewList[0]._data
print OldList[0]._data

والجري في قذيفة الثعبان يعطي النص التالي. ويمكننا أن نرى قائمة تبذل مع نسخ من الأشياء القديمة. يمكن للمرء أن الكائنات ديك حالته تجديد بالرجوع من خلال القائمة القديمة، ويمكن أن تكون التحديثات رأيت عند الوصول إلى الكائن من خلال القائمة القديمة. وأخيرا، تغيير المرجعية في القائمة الجديدة يمكن أن ينظر إلى لا تعكس في القائمة القديمة، كما قائمة جديدة الآن يشير إلى كائن آخر.

>>> # ================================================================
... # === ShallowCopy.py =============================================
... # ================================================================
... #
... class Foo:
...     def __init__(self, data):
...         self._data = data
...
>>> aa = Foo ('aaa')
>>> bb = Foo ('bbb')
>>>
>>> # The initial list has two elements containing 'aaa' and 'bbb'
... OldList = [aa,bb]
>>> print OldList[0]._data
aaa
>>>
>>> # The shallow copy makes a new list pointing to the old elements
... NewList = OldList[:]
>>> print NewList[0]._data
aaa
>>>
>>> # Updating one of the elements through the new list sees the
... # change reflected when you access that element through the
... # old list.
... NewList[0]._data = 'xxx'
>>> print OldList[0]._data
xxx
>>>
>>> # Updating the new list to point to something new is not reflected
... # in the old list.
... NewList[0] = Foo ('ccc')
>>> print NewList[0]._data
ccc
>>> print OldList[0]._data
xxx

وكما سبق الرد عليه، وأنا ببساطة إضافة مظاهرة بسيطة:

>>> a = [1, 2, 3, 4]
>>> b = a
>>> c = a[:]
>>> b[2] = 10
>>> c[3] = 20
>>> a
[1, 2, 10, 4]
>>> b
[1, 2, 10, 4]
>>> c
[1, 2, 3, 20]

وأعتقد أبدا بأن "= ب 'في بيثون تعني" نسخة ب ل. إذا كانت هناك متغيرات على كلا الجانبين، لا يمكنك معرفة ذلك حقا. بدلا من ذلك، أعتقد أنها "تعطي ب على اسم إضافي".

إذا ب هو كائن غير قابل للتغيير (مثل عدد، الصفوف (tuple) أو سلسلة)، ثم نعم، وأثر هو أن تحصل على نسخة منه. ولكن هذا لأنه عندما كنت تتعامل مع immutables (والذي ربما كان ينبغي أن يسمى <م> للقراءة فقط ، <م> غير قابلة للتغيير أو <م> دودة ) لك <م> دائما الحصول على نسخة منه، عن طريق التعريف.

إذا ب هي قابلة للتغيير، وكنت <م> دائما أن تفعل شيئا اضافية للتأكد من لديك نسخة حقيقية . دائما . مع القوائم، انها بسيطة مثل شريحة: أ = ب [:].

وقابلية التحول هو أيضا السبب في أن هذا:

def myfunction(mylist=[]): 
    pass

... لا تفعل تماما ما كنت أعتقد أنه يفعل.

إذا كنت من C-الخلفية: ما تبقى من '=' هو مؤشر، دائما. كل المتغيرات هي مؤشرات دائما. إذا وضعت المتغيرات في القائمة: أ = [ب، ج]، كنت قد وضعت مؤشرات إلى أشارت القيم التي كتبها ب و ج في قائمة المشار إليه بواسطة أ. إذا كنت ثم وضع [0] = د، المؤشر في موقف 0 يشير الآن إلى أي نقطة d ل.

وانظر أيضا نسخة وحدة: http://docs.python.org/library/ copy.html

نسخة الضحلة: (نسخ قطع من الذاكرة من موقع واحد إلى آخر)

a = ['one','two','three']

b = a[:]

b[1] = 2

print id(a), a #Output: 1077248300 ['one', 'two', 'three']
print id(b), b #Output: 1077248908 ['one', 2, 'three']

نسخة عميق: (نسخ كائن مرجع)

a = ['one','two','three']

b = a

b[1] = 2


print id(a), a #Output: 1077248300 ['one', 2, 'three']
print id(b), b #Output: 1077248300 ['one', 2, 'three']
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top