Asosiy mazmunga o'tish

9-dars: Ro'yxat va o'zgaruvchanlik

3-blokMa'lumotni saqlash9–12 darslar

Bu darsdan keyin siz

  • ro’yxat yaratasiz, elementga murojaat qilasiz va o’zgartirasiz
  • b = a nusxa OLMASLIGINI id() bilan isbotlaysiz
  • haqiqiy nusxa olishning uch usulini bilasiz

Ro’yxat kvadrat qavslar bilan yoziladi va tartibni saqlaydi. Indeks noldan boshlanadi, manfiy indeks oxiridan sanaydi: royxat[-1] — oxirgi element.

o'zgaruvchanmutable

Yaratilgandan keyin ichini o’zgartirish mumkin bo’lgan obyekt. Ro’yxat, lug’at, to’plam — o’zgaruvchan. Son, satr, tuple — o’zgarmas.

royxat.py
baholar = [5, 4, 3]baholar[0] = 2          # ichini o'zgartirdikbaholar.append(5)       # oxiriga qo'shdikprint(baholar)          # [2, 4, 3, 5]print(len(baholar))     # 4

append oxiriga qo’shadi, insert kerakli joyga, remove qiymat bo’yicha o’chiradi, pop indeks bo’yicha o’chirib qiymatni qaytaradi.

2-darsdan esingizda: = qiymatni ko’chirmaydi, yorliqni bog’laydi. Sonlar bilan bu xavfsiz edi — son o’zgarmas, uni «ichidan» o’zgartirib bo’lmaydi. Ro’yxat esa o’zgaruvchan, shu sababli qoida birdan sezilib qoladi.

aliasing.py
a = [1, 2, 3]b = a               # nusxa OLINMADIb.append(4)print(a)            # [1, 2, 3, 4] — a ham o'zgardi!print(id(a) == id(b))   # True — bitta obyekt

Nusxa kerak bo’lsa uni ochiq so’rash kerak. Uch usul bir xil natija beradi: b = a.copy(), b = a[:], b = list(a).

nusxa.py
a = [1, 2, 3]b = a.copy()b.append(4)print(a, b)             # [1, 2, 3] [1, 2, 3, 4]print(id(a) == id(b))   # False — ikki obyekt

Bu «yuza nusxa»: ro’yxat ichida boshqa ro’yxat bo’lsa, ichkilar hamon umumiy qoladi. Ichma-ich tuzilmalar 12-darsda ko’riladi.

Avval o'ylang: bu kod nima chiqaradi? Ishga tushirishdan oldin yozing.

Bashorat qiling
a = [1, 2, 3]b = ab.append(4)print(a)print(b)
Javobni ko'rish
[1, 2, 3, 4]
[1, 2, 3, 4]

Bitta obyekt, ikki yorliq. b orqali qo'shilgan element a orqali ham ko'rinadi — ikkalasi bir xil ro'yxatga qaraydi.

Avval o'ylang: bu kod nima chiqaradi? Ishga tushirishdan oldin yozing.

Bashorat qiling
a = [1, 2, 3]b = a.copy()b.append(4)print(a)print(b)
Javobni ko'rish
[1, 2, 3]
[1, 2, 3, 4]

copy() yangi obyekt yasadi. Endi ikki alohida ro'yxat bor va biri o'zgarganda ikkinchisi tegilmaydi.

Ikki senariyni yonma-yon solishtiring. Xotira strelkalariga qarang: birinchi senariyda ikki nom bitta ro’yxatga, ikkinchisida ikki alohida ro’yxatga boradi.

Aliasing ko'rsatuvchi

Ikki senariyni qadamlab solishtiring: yorliq nusxa emas. Klaviatura: → keyingi qadam.

Bu simulyator ikki senariyni yonma-yon ko'rsatadi. Birinchisida b = a yozilgan: nusxa olinmaydi, ikki nom bitta ro'yxatga qaraydi, shuning uchun b.append(4)a ni ham o'zgartiradi. Ikkinchisida b = a.copy() — ikki alohida ro'yxat.

JavaScript'siz sinash: VS Code'da a = [1, 2, 3], b = a, b.append(4),print(a, b), print(id(a), id(b)) yozib ishga tushiring. Keyin b = a nib = a.copy() ga o'zgartirib qayta ishga tushiring va farqni yozib qo'ying.

  1. a = [1, 2, 3]
  2. b = a
  3. b.append(4)
  4. print(a)

Xotira

a
b
id: —
id: —

«Keyingi qadam» bilan boshlang va har qadamda xotiraga qarang.

Bu darsda bir joyni tushunmasangiz — keyingi darslarda qoqilib turasiz. Simulyatorni ikki senariyda ham oxirigacha o’tkazib, id raqamlarini solishtiring.

Bu kod ataylab buzuq — xatoni toping

Buzuq kod
asl = [5, 4, 3]tahrir = asltahrir.remove(4)print("Asl:", asl)print("Tahrir:", tahrir)

Python shunday javob beradi:

Asl: [5, 3]
Tahrir: [5, 3]
(kutilgan: Asl [5, 4, 3], Tahrir [5, 3])
Sababi va tuzatish

Nusxa olinmagan: tahrir va asl bitta ro'yxatga qaraydi. remove o'sha yagona obyektdan elementni o'chirdi.

To’g’risi: tahrir = asl.copy(). Bu xato Python xabar bermaydigan turdan — kod ishlaydi, faqat natija noto’g’ri. Shuning uchun ro’yxatni «nusxa olib» o’zgartirmoqchi bo’lsangiz, copy() ni yozganingizni tekshirish odat bo’lishi kerak.

1b = a bajarilgandan keyin id(a) va id(b) teng bo'ladimi?

Javobni ko'rish

Ha. Nusxa olinmagan — ikki yorliq bitta obyektga qaraydi.

2Nega bu muammo sonlarda sezilmaydi, ro'yxatda sezildi?

Javobni ko'rish

Son o’zgarmas: uni ichidan o’zgartirib bo’lmaydi, faqat yorliqni boshqa obyektga ko’chirish mumkin. Ro’yxat esa o’zgaruvchan — append obyektning o’zini o’zgartiradi, shuning uchun barcha yorliqlarda ko’rinadi.

3Ro'yxatning haqiqiy nusxasini olishning uch usulini yozing.

Javobni ko'rish

a.copy(), a[:], list(a). Uchtasi ham yangi obyekt yasaydi.

4royxat[-1] nimani beradi va nima uchun bu qulay?

Javobni ko'rish

Oxirgi elementni. Qulay, chunki ro’yxat uzunligini bilish kerak emas — royxat[len(royxat) - 1] yozishdan qisqa va xatosiz.

5a = [1, 2, 3], b = a, keyin b = [9] yozildi. a nima bo'ladi?

Javobni ko'rish

a o’zgarmaydi: [1, 2, 3]. Bu safar obyekt o’zgartirilmadi — b yorlig’i butunlay yangi ro’yxatga ko’chdi.

Topshiriq — darajangizni tanlang

Asos · 5–7-sinf — Vizual va aniq ko'rsatmali

Besh sevimli taomingizdan ro’yxat tuzing. Birinchi va oxirgi elementni chiqaring, bittasini o’zgartiring, yangisini qo’shing, bittasini o’chiring — har qadamdan keyin ro’yxatni chiqaring. So’ng b = a va b = a.copy() ni ikki alohida faylda sinab, natijalar farqini daftarga yozib keling.

Mustahkam · 8–9-sinf — Matnli masala, o'zingiz tuzasiz

Sinf ro’yxati bilan ishlovchi programma yozing: asl ro’yxatni saqlab qolib, undan «tahrirlangan» nusxa yasang (ikki ism qo’shib, bittasini o’chirib). Programma oxirida ikki ro’yxatni ham chiqarib, id() larini solishtirib ko’rsatsin. Nusxa olishni unutgan variantni ham yozib, farqni izohlang.

Chuqur · 10–11-sinf — Algoritmik, chegara holatlari bilan

Funksiya yozing: qosh(royxat, element) — ro’yxatga element qo’shsin. Ikki variantda: birinchisi kelgan ro’yxatni o’zgartiradi, ikkinchisi nusxa qaytaradi va aslga tegmaydi. Har ikkisini sinab, qaysi biri xavfsizroq va nega — bir paragrafda yozing. Qo’shimcha: def f(royxat=[]) shaklidagi standart argument nega xavfli? (Bu xato 20-darsda AI kodida qidiriladigan uch xatodan bittasi.)

Darsni belgilash uchun JavaScript kerak. Bu progressni saqlash uchun ishlatiladi — darslikning o'zi JavaScript'siz ham to'liq o'qiladi.