اذهب إلى المحتوى

السؤال

نشر

قمت بعمل مجموعة من القوائم بهذه الطريقة:

Arr = [[0] * 5] * 3

وحصلت على النتيجة المرغوبة وهي:

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

لكن عندما أردت أن أغير أول عنصر فقط كالتالي:

Arr[0][0] = 1

وجدت أن كل أول عنصر في كل قائمة أصبح يساوي 1

[[1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0]]

لم أفهم لماذا حدث هذا الأمر؟ ولا كيفية تعديل أول عنصر فقط؟

Recommended Posts

  • 1
نشر

إن السبب في هذه النتيجة أن عملية الضرب بعد تشكيل المصفوفة تقوم بتكرار القيمة لنفس الكائن (المصفوفة المكونة من 5 أصفار) وتأخذه بالمرجع بآلية shallow lists.

حيث: في القائمة الأولى لا تُنشئ بايثون 5 كائنات أعداد صحيحة ولكنها تنشئ فقط كائنًا صحيحًا واحدًا وكل مؤشرات المصفوفة تشير إلى كائن int نفسه كما هو موضح في الرسم المرفق و النتيجة في المثال.

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

والحل هو إنشاء كل سطر في المصفوفة على حدى:

arr = [[0 for i in range(5)] for j in range(3)]
 

[0][0] = 1
print(arr)
 
[[1, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]

صورة توضيحية:

2d_array_changed.png

في الحالة الأولى عند طباعة عناوين الذاكرة لكل مصفوفة ستكون تشير لنفس العنوان:

Arr = [[0] * 5] * 3
Arr[0][0] = 1
print(Arr)

print (id(Arr[0]))
print (id(Arr[1]))
print (id(Arr[2]))

#1221247140608
#1221247140608
#1221247140608

 

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...