سؤال

أنا أقرأ كيف يفكر مثل عالم الكمبيوتر وهو نص تمهيدي عن "البرمجة بايثون".

أريد أن أوضح سلوك ضرب المشغل (*) عندما يطبق على القوائم.

النظر في وظيفة make_matrix

def make_matrix(rows, columns):
"""
  >>> make_matrix(4, 2)
  [[0, 0], [0, 0], [0, 0], [0, 0]]
  >>> m = make_matrix(4, 2)
  >>> m[1][1] = 7
  >>> m
  [[0, 0], [0, 7], [0, 0], [0, 0]]
"""
return [[0] * columns] * rows

الانتاج الفعلي هو

[[0, 7], [0, 7], [0, 7], [0, 7]]

الإصدار الصحيح من make_matrix هو :

def make_matrix(rows, columns):
"""
  >>> make_matrix(3, 5)
  [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
  >>> make_matrix(4, 2)
  [[0, 0], [0, 0], [0, 0], [0, 0]]
  >>> m = make_matrix(4, 2)
  >>> m[1][1] = 7
  >>> m
  [[0, 0], [0, 7], [0, 0], [0, 0]]
"""
matrix = []
for row in range(rows):
    matrix += [[0] * columns]
return matrix

السبب في النسخة الأولى من make_matrix فشل ( كما هو موضح في الكتاب في 9.8 ) هو أن

...كل صف هو مستعار من الصفوف الأخرى...

وأتساءل لماذا

[[0] * columns] * rows

أسباب ...كل صف هو مستعار من الصفوف الأخرى...

ولكن ليس

[[0] * columns]

أيلماذا كل [0] في صف واحد هو مستعار من صف آخر عنصر.

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

المحلول

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

عندما تفعل

innerList = [0] * 10

يمكنك إنشاء قائمة مع 10 عناصر، كلهم يشيرون إلى نفسه int هدف 0.

منذ كائنات عدد صحيح ثابت, ، عندما تفعل

innerList[1] = 15

أنت تغير العنصر الثاني من القائمة بحيث يشير إلى عدد صحيح آخر 15. وبعد هذا يعمل دائما بسبب int الكائنات الدخانية.

لهذا

outerList = innerList * 5

سوف تنشئ أ list كائن مع 5 عناصر، كل واحد هو إشارة إلى نفس الشيء innerList على النحو الوارد أعلاه. لكن منذ list الكائنات متقلب:

outerList[2].append('something')

بالضبط مثل:

innerList.append('something')

لأنهم مراجعان إلى نفس list هدف. وبعد لذلك ينتهي العنصر في هذا واحد list. وبعد يبدو أنه مكررة، لكن الحقيقة هي أن هناك واحدة فقط list الكائن، والعديد من المراجع إليها.

على النقيض من ذلك إذا قمت بذلك

outerList[1] = outerList[1] + ['something']

ها انت خلق اخر list هدف (استخدام + مع القوائم هي نسخة واضحة)، وتعيين مرجع إليها في المرتبة الثانية من outerList. وبعد إذا كنت "إلحاق" العنصر بهذه الطريقة (لا تملك حقا، ولكن إنشاء قائمة أخرى)، innerList سوف لا تتأثر.

نصائح أخرى

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

[[0] * columns] * rows

عفوا لقد قدمت قائمة كبيرة من المؤشرات [0].تغيير واحد و تغيير كل منهم.

الاعداد الصحيحه لا يتم تمرير من قبل المرجعية ، هم حقا نسخ, ولذلك [0] * المحتويات هو حقا جعل الكثير من 0 و إلحاق لهم قائمة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top