Съдържание на курса
Тензори от нулата (1): едно число, един списък, една таблица, един куб
От Dorian Chávez · основател и главен изпълнителен директор на Hábil ·
Обновено на 21 октомври 2026 г.
Какво е тензор, разказано със списъците на Python, които вече умееш да пишеш, и защо Айнщайн трябваше да помоли един приятел за помощ, за да го разбере.
Тензори от нулата · урок A, сесия 1 от 8
Сценарий: героите и историята са измислени. Техническите и историческите данни и реалните цифри са с посочен източник.
Неделя, 1 ноември, 11:52 вечерта
Телефонът на доня Лупе завибрира върху нощното шкафче. Веднъж. Тя, която никога не отговаря на нищо след десет, го обърна просто по навик.
Засякохме необичайни плащания в терминала на вашия клон Norte. Терминалът е спрян, докато трае проверката.
Прочете го три пъти. После седна на ръба на леглото, с очилата на челото, и повече не заспа.
Понеделник, 2 ноември, 9:10 сутринта
— Госпожо Ерера, добро утро. Обажда се господин Ортега от банката.
Официален глас. Бързането на човек, когото чакат още четиридесет обаждания.
— Имате срок до 23 декември да ни докажете кои плащания от този терминал са реални продажби. Иначе го закриваме.
— До 23-ти? Господин Ортега, сезонът е! Без терминал в Norte, през декември…
— Затова ви давам срок. Приятен ден.
Щрак.
Понеделник, 2 ноември, 7:40 вечерта. Книжарницата, клон Centro.
Мирис на нова хартия и на гума за триене. Металната ролетка, спусната наполовина, стърже всеки път, щом мине камион. Матео Риос, на 20 години, втори семестър информатика, влиза приведен, с раницата на рамо и лаптопа под мишница.
— Лельо, мама каза, че е спешно.
Доня Лупе не го поздравява. Слага телефона пред него, със съобщението от банката.
— Ти нали разбираш от компютри.
Матео го прочита. Стомахът му изстива.
— Лельо, аз знам основен Python. Това е… нещо друго.
— Тогава научи другото нещо. Имаш време до 23 декември. — Скръства ръце. — И не ми казвай „не“, че нали аз ти платих таксата.
Матео отваря лаптопа на тезгяха, между буркан с моливи и купчина картони. Знае със сигурност само едно: банката не е видяла книжарница. Видяла е числа. Ако иска да защити леля си, трябва да се научи да вижда същото, което вижда банката.
И ти ще се учиш заедно с него.
Тази поредица има два урока от по четири сесии, по една сесия седмично. В първия урок, От списъка до куба, научаваш какво е тензор, как да го създаваш, да го обхождаш и да го обобщаваш. Във втория, Тензорите в действие, му променяш формата, извършваш операции с целия тензор, обучаваш с него модел, който открива измами, и виждаш къде се появява в една банка, един застраховател и един магазин.
| Сесия | Какво виждаш | Упражнения |
|---|---|---|
| 1 — Едно число, един списък, една таблица, един куб | Какво е измерение, как се броят измеренията и какво е формата на тензор, всичко със списъци на Python | Упражнения 1 до 5 |
| 2 — Твоят първи тензор | Инсталиране на PyTorch, превръщане на списъците ти в тензори, shape и dtype |
Упражнения 6 до 9 |
| 3 — Осите имат имена | Извличане на част от тензора по която и да е от осите му | Упражнения 10 до 13 |
| 4 — Сумиране по лист | Суми и средни стойности по ос, сравнени с един for |
Упражнения 14 до 17, самооценка и преговор на урока |
Всяка сесия е от около 2 часа: горе-долу един за четене и следване на примера и един за упражнения. От сесия 2 нататък всяка започва с 3 въпроса за преговор от предишната, на които се отговаря, без да се поглежда.
Какво трябва да знаеш предварително: основен Python: променливи, if, for и while, функции, списъци и кортежи. Ако идваш от курса по Python на Hábil, това са уроците му от 0 до 4. Какво трябва да имаш: Python 3 и текстов редактор. Днес не инсталираш нищо друго.
Кодът на тази сесия е в публичното хранилище на курса, в папката
sesion-01: github.com/HabilMX/curso-tensores. Първо го напиши сам, защото така се учи; хранилището е за сравнение, когато нещо не ти излезе по същия начин. Всяка програма идва с изхода, който трябва да получиш.
Цели на тази сесия
В края ще можеш да правиш тези четири неща. До всяко е упражнението, което го доказва.
| # | В края можеш… | Доказва го |
|---|---|---|
| 1 | При даден набор от данни (продажби, оценки, снимка) да кажеш колко измерения има и какво представлява всяко | Упражнение 1 |
| 2 | Да запишеш тези данни като вложени списъци на Python и да посочиш едно число с индексите му | Упражнения 2 и 4 |
| 3 | Да изчислиш формата на тензор (колко елемента има във всяко измерение) ръчно и с функция | Упражнения 1 и 3 |
| 4 | Да разпознаеш кога една таблица не може да бъде тензор, защото е крива, и да го провериш с код | Упражнение 5 |
Защо е важно
Същата вечер, докато доня Лупе брои рестото в касата, Матео търси в телефона си как една банка решава, че нещо е „необичайно“. Отговорът малко го плаши.
Банката не чете една покупка така, както я четеш ти. Превръща я в числа: сумата, часа, разстоянието до последната покупка, колко покупки е имало през последния час. Една покупка се превръща в списък от числа. Хиляда покупки — в таблица. Покупките на всеки клиент през последните 30 дни — в куб.
Никой в банката не е видял лицата на клиентите от Norte. Една машина е видяла кубове от числа и нещо не ѝ се е връзвало.
И не е само банката. Когато застрахователят получи снимка на ударена кола, той също не вижда кола. Вижда мрежа от точки, и всяка точка носи три числа: колко червено, колко зелено и колко синьо има в нея. Отново куб от числа.
Почти всички системи с изкуствен интелект, за които ще чуваш в кариерата си, работят така: първо превръщат света в подредени кутии с числа, а после смятат с тези кутии. Тези кутии се наричат тензори. Ако разбираш как са подредени, разбираш половината от това, което прави един модел. Другата половина я виждаме във втория урок.
— И това с какво се яде? — пита доня Лупе, без да вдига поглед от монетите.
— Със списъци, лельо. Списъци в списъци.
Вярно е, и това е добрата новина: вече умееш да записваш данните на един тензор. Това са списъци в списъци, само от числа и добре подравнени. В сесия 2 ще ги превърнеш в истински тензори.
Случаят: книжарницата на доня Лупе
Доня Лупе има книжарница с два клона, Centro и Norte. Продава три неща, които са ѝ важни: тетрадки, химикалки и раници. Числата в тази поредица са примерни, но формата на данните е като на всеки бизнес.
Матео още не знае какво търси. Затова прави единственото разумно нещо: започва от лесното и иска все повече подробности. Пита леля си за продажбите от миналата седмица четири пъти, всеки път с по-силна лупа.
Стъпка 1 — Едно число
Доня Лупе спуска ролетката докрай. Металният шум отеква в целия магазин.
— Лельо, колко продадохте миналата седмица? — $18,500, в Centro. И не ме питай още за Norte, че ми скача кръвното.
total = 18500
Едно-единствено число. За да го посочиш, не ти трябва никакво сведение: има само едно. Казваме, че има нула измерения. На езика на тензорите се нарича скалар.
Скаларът казва много и обяснява малко. С $18,500 никой не може да защити нищо пред банка.
Стъпка 2 — Един списък
— А ден по ден? — Понеделник 2,500; вторник 3,100; сряда 2,200; четвъртък 2,800; петък 3,900; събота 2,400; неделя 1,600. — Казва го наизуст, като молитва.
por_dia = [2500, 3100, 2200, 2800, 3900, 2400, 1600]
Сега вече ти трябва едно сведение, за да посочиш число: денят. por_dia[4] е петък, 3,900 (помни, че индексите започват от 0). Една посока, едно измерение. Нарича се вектор.
Провери, че нищо не се е изгубило: sum(por_dia) дава 18500, същата сума като в стъпка 1. Подробностите не променят сумата; само я разпределят.
Матео записва нещо на едно лепящо листче: подробностите не лъжат; сумата крие. Още не знае колко ще му послужи тази фраза.
Стъпка 3 — Една таблица
— А по ден и по продукт?
Доня Лупе изпуфтява, вади стария си лаптоп, онзи със стикера на Дева Мария, и отваря електронната си таблица:
| Ден | Тетрадки | Химикалки | Раници |
|---|---|---|---|
| Понеделник | 1,200 | 800 | 500 |
| Вторник | 1,500 | 900 | 700 |
| Сряда | 1,000 | 700 | 500 |
| Четвъртък | 1,300 | 900 | 600 |
| Петък | 2,000 | 1,200 | 700 |
| Събота | 1,200 | 800 | 400 |
| Неделя | 800 | 500 | 300 |
В Python всеки ред е списък, а таблицата е списък от редове:
por_dia_y_producto = [
[1200, 800, 500], # lunes
[1500, 900, 700], # martes
[1000, 700, 500], # miércoles
[1300, 900, 600], # jueves
[2000, 1200, 700], # viernes
[1200, 800, 400], # sábado
[800, 500, 300], # domingo
]
За да посочиш число, ти трябват две сведения: денят и продуктът. por_dia_y_producto[4][2] е петък (ред 4), раници (колона 2): 700. Две посоки, две измерения. Нарича се матрица.
Обърни внимание на реда: първо редът, после колоната. Тази подредба не е каприз; това е редът, в който си написал списъците. Външният са дните; вътрешните — продуктите.
— Значи всяко число си има адрес — казва доня Лупе.
— Точно така, лельо. Ден и продукт. Улица и номер.
Стъпка 4 — Един куб: таблицата с листове
Тогава Матео задава въпроса, който леля му отбягваше.
— А клонът Norte?
Тишина. Доня Лупе щраква върху другия лист на същата таблица, бавно, като човек, който отваря плик с лоши новини. Същата форма — 7 дни, 3 продукта — други числа. Таблицата ѝ вече има два листа, по един за всеки клон, и всеки лист е таблица.
Pestaña «Centro» Pestaña «Norte»
Cuad. Plumas Moch. Cuad. Plumas Moch.
Lun 1200 800 500 Lun 300 200 100
Mar 1500 900 700 Mar 400 250 150
Mié 1000 700 500 Mié 350 200 100
Jue 1300 900 600 Jue 300 150 100
Vie 2000 1200 700 Vie 500 300 200
Sáb 1200 800 400 Sáb 300 200 100
Dom 800 500 300 Dom 200 100 100
Матео гледа двата листа един до друг. Нещо го човърка отвътре. Но първо трябва да вкара всичко в Python.
В Python цялата таблица е списък от листове:
centro = por_dia_y_producto
norte = [
[300, 200, 100],
[400, 250, 150],
[350, 200, 100],
[300, 150, 100],
[500, 300, 200],
[300, 200, 100],
[200, 100, 100],
]
papeleria = [centro, norte]
За да посочиш число, ти трябват три сведения: клонът, денят и продуктът. papeleria[1][4][2] е Norte (лист 1), петък (ред 4), раници (колона 2): 200. Три посоки, три измерения. Вече няма специално име: това е тензор с три измерения.
Това е образът, който е добре да запомниш от цялата поредица: тензорът с три измерения е електронна таблица с листове, в която всички листове имат едни и същи колони и един и същ брой редове.
| Какво имаш | За да посочиш число, ти трябва | Измерения | Име |
|---|---|---|---|
| $18,500 | нищо: има само едно | 0 | скалар |
| Продажби за 7 дни | денят | 1 | вектор |
| Продажби по ден и продукт | денят и продуктът | 2 | матрица |
| Същото, по клон | клонът, денят и продуктът | 3 | тензор с 3 измерения |
Правилото, което обобщава всичко: броят на измеренията е броят на сведенията, които ти трябват, за да посочиш едно-единствено число. Всяка от тези посоки се нарича още ос; ще срещаш и двете думи.
— И това ли е всичко? Един куб? — Доня Лупе го поглежда над очилата. — Аз пък мислех, че банката използва неща от НАСА.
— Използва кубове, лельо. Само че много големи.
Стъпка 5 — Броене на измеренията с код
Да броиш скоби на око става с малки примери. С онова, което банката държи в ръцете си — не. Матео го знае: ако ще се бори срещу машина, неговата трябва да брои сама. Преди това — Python-ът, който ще използваш оттук нататък, в случай че не ти е пресен:
type(x) == listпроверява далиxе списък.x[0]взема първия елемент;len(x)брои колко са.lista.append(valor)добавя стойност в края на списък;tuple(lista)го превръща в кортеж.
Създай файл dimensiones.py със списъците от стъпки 1 до 4 и, над тях, тази функция:
def contar_dimensiones(x):
dimensiones = 0
while type(x) == list:
dimensiones = dimensiones + 1
x = x[0]
return dimensiones
Как работи: помисли за матрьошките. Докато онова, което държи в ръка, е списък, функцията отваря кутията — взема първия елемент, x[0] — и брои едно. Когато онова, което излиза, вече е число, спира. Списък от списъци от списъци се отваря три пъти: три измерения. Число не се отваря нито веднъж: нула.
Добави в края на файла:
if __name__ == "__main__":
print(contar_dimensiones(total))
print(contar_dimensiones(por_dia))
print(contar_dimensiones(por_dia_y_producto))
print(contar_dimensiones(papeleria))
Изпълни го с python3 dimensiones.py:
0
1
2
3
Редът if __name__ == "__main__": е подробност на Python: кара кода под него да се изпълнява само когато пускаш този файл директно. Засега го копирай както е.
Четири числа на екрана. Доня Лупе надниква.
— Готово ли е? Това ли ще спаси Norte?
— Не, лельо. Това ми казва, че разбирам какво имам. А то не е малко.
Стъпка 6 — Формата: колко има във всяка посока
Не стига да знаеш, че книжарницата има три измерения. Един детектив не записва „има заподозрени“: записва колко. Матео също иска да знае колко елемента има във всяко от тях: 2 клона, 7 дни, 3 продукта. Това се нарича форма на тензора и се записва като кортеж: (2, 7, 3).
Формата ти казва много с един поглед:
- Колко измерения има: колко числа съдържа кортежът (3).
- Колко е голямо всяко: 2, 7 и 3.
- Колко числа има общо: умножават се, 2 × 7 × 3 = 42.
Четиридесет и две числа. Цяла седмица на два клона се побира в четиридесет и две числа.
Функцията е почти същата като предишната. Вместо да брои, записва дължината на всяка кутия, която отваря:
def forma(x):
tamanos = []
while type(x) == list:
tamanos.append(len(x))
x = x[0]
return tuple(tamanos)
Замени последния блок на файла си с този:
if __name__ == "__main__":
print("total", contar_dimensiones(total), forma(total))
print("por_dia", contar_dimensiones(por_dia), forma(por_dia))
print("por_dia_y_producto", contar_dimensiones(por_dia_y_producto), forma(por_dia_y_producto))
print("papeleria", contar_dimensiones(papeleria), forma(papeleria))
assert forma(papeleria) == (2, 7, 3), "La papelería debería ser 2 sucursales × 7 días × 3 productos"
print("Todo cuadra")
Изход:
total 0 ()
por_dia 1 (7,)
por_dia_y_producto 2 (7, 3)
papeleria 3 (2, 7, 3)
Todo cuadra
Две нови неща в този изход:
(7,)има запетая, защото така Python записва кортеж с един елемент. Без запетаята(7)би било просто числото 7.()е празен кортеж: скаларът няма нито една посока.
И един нов ред в кода: assert. Означава „това трябва да е вярно“. Той е като охраната на входа: ако е вярно, нищо не се случва и програмата продължава. Ако не е, програмата спира и ти казва защо. Опитай: смени (2, 7, 3) с (7, 2, 3) и я изпълни отново:
Traceback (most recent call last):
...
AssertionError: La papelería debería ser 2 sucursales × 7 días × 3 productos
Върни го на (2, 7, 3). Така ще работиш в цялата поредица: всяко упражнение идва със своя assert и програмата сама ти казва дали си сгрешил, без да чакаш някой да те провери.
— „Todo cuadra“, всичко се връзва — прочита на глас доня Лупе. — Дано и банката мислеше така.
Стъпка 7 — Кога един списък от списъци НЕ е тензор
Наближава десет. Матео се прозява и му хрумва неудобният въпрос: ами ако някой ден някой изпрати непълен лист? Дали функцията му ще забележи?
Има едно условие, което не подлежи на преговори: всички кутии на едно и също ниво трябва да са с еднакъв размер. Всички листове със 7 реда, всички редове с 3 колони. Тензорът е правоъгълен.
Погледни този списък:
chueca = [[1, 2, 3], [4, 5]]
Python го приема без проблем: това е списък от два списъка. Но първият ред има 3 елемента, а вторият — 2. Това не е таблица, а крива таблица. И нашите функции те лъжат право в очите:
>>> contar_dimensiones(chueca)
2
>>> forma(chueca)
(2, 3)
forma казва (2, 3), защото е измерила само първия ред. Като свидетел, който е видял първата пресечка и се кълне за цялата улица. Ако ѝ се довериш и поискаш chueca[1][2], програмата хвърля грешка:
IndexError: list index out of range
Затова трябва проверка. За таблица (две измерения) тази функция сравнява дължината на всеки ред с тази на първия. При повече измерения проверката е по-дълга; не се притеснявай, в следващата сесия PyTorch я прави изцяло вместо теб:
def es_rectangular(tabla):
largo = len(tabla[0])
for fila in tabla:
if len(fila) != largo:
return False
return True
>>> es_rectangular(por_dia_y_producto)
True
>>> es_rectangular(chueca)
False
Библиотеките за ИИ, като PyTorch, правят тази проверка вместо теб: когато превръщаш крив списък в обикновен тензор, отказват. Ще го видиш в следващата сесия. (Съществуват специални тензори за неравномерни данни, но в тази поредица не ги използваме.)
Матео се загледва в това False. Кривите данни не предупреждават. Крият се, докато нещо не се срине.
Отвъд три: пощенският адрес
— А ако ти поискам четири седмици, лельо, вместо една?
— Ще ти ги дам. Но ще ми помогнеш да подредя картоните.
С продажбите за 4 седмици на Матео ще му трябват четири сведения, за да посочи число: седмица, клон, ден и продукт. Четири измерения, форма (4, 2, 7, 3).
Четири измерения не могат да се нарисуват, но се разбират точно като пощенски адрес. За да стигнеш до един апартамент, даваш щата, квартала, сградата, етажа и номера на апартамента: пет сведения, пет измерения. Никой не се плаши от това. Всяко сведение избира кутия в предишната, точно както всеки индекс в papeleria[1][4][2].
Някои реални тензори, които ще срещнеш:
| Какво е | Измерения | Примерна форма |
|---|---|---|
| Малка цветна снимка | височина × ширина × цвят | (480, 640, 3) |
| Партида (batch) от 32 снимки | снимка × височина × ширина × цвят | (32, 480, 640, 3) |
| 10 секунди видео при 30 кадъра в секунда | кадър × височина × ширина × цвят | (300, 720, 1280, 3) |
| Дневно обобщение за 1,000 клиенти в продължение на 30 дни, с 5 стойности на клиент и ден | клиент × ден × стойност | (1000, 30, 5) |
Тук записваме снимките като височина × ширина × цвят, защото така излизат нашите списъци. Редът не е универсален: в много програми с PyTorch ще видиш цвят × височина × ширина. Важното е да знаеш какво е всяка ос.
Това видео, записано без компресия, е 829,440,000 числа (умножи формата). Затова видеата се съхраняват компресирани (един файл MP4 съдържа компресирано видео), и затова работата с некомпресирано видео изисква много памет.
Матео гледа последния ред на таблицата: 1,000 клиенти, 30 дни, 5 стойности. Горе-долу така трябва да изглежда онова, което банката има за терминала в Norte. А той едва е стигнал до 42 числа.
Откъде дойде думата „тензор“?
Вече е минало полунощ, а Матео е още буден в стаята си. Не може да спре да чете. Оказва се, че инструментът, който ще използва срещу банката, има история с хора, заседнали точно колкото него.
Никой не е измислил тензорите сам.
1846. Ирландецът Уилям Роуън Хамилтън използва за първи път думата tensor, от латинското tendere, „разтягам“. Но за него тя означава друго: големината на кватернион, вид число, което самият той е измислил. Думата се ражда, но още не знае какво ще стане.
1898. Германецът Волдемар Фойгт ѝ дава съвременния смисъл. Изучава кристали, които се разтягат и деформират различно според посоката, в която ги дърпаш, и му трябва едно-единствено нещо, което да пази всички тези посоки едновременно. Една кутия за много посоки. Звучи ти познато, нали?
1900. Италианците Грегорио Ричи-Курбастро и Тулио Леви-Чивита публикуват, добре подредена, математиката, която днес наричаме тензорно смятане (те я наричали „абсолютно диференциално смятане“). И тук има подробност, която прилича на следа от роман: в цялата им статия думата „тензор“ не се появява нито веднъж.
1912. Алберт Айнщайн се връща в Цюрих, заседнал с теорията си за гравитацията. Сметките не му излизат. Търси приятеля си от университета, математика Марсел Гросман. Според спомените на един техен общ състудент години по-късно, Айнщайн му казал:
— Гросман, помогни ми, иначе ще полудея.
Гросман му показва работата на италианците. Тази на Ричи-Курбастро и Леви-Чивита. Онази, в която не пишеше „тензор“.
1915. Март. За Айнщайн пристига писмо. Подписано е от Леви-Чивита. Пише му, че едно доказателство във версията на теорията му от онова време е грешно.
Представи си: Айнщайн, поправен с писмо.
Писмата се разменят до май. Айнщайн упорито защитава доказателството си. Писмата отиват и се връщат. Накрая Айнщайн приема, че то е непълно. В писмо от 2 април му пише: „Никога не съм имал толкова интересна кореспонденция“. Месеци по-късно сменя посоката и на 25 ноември представя окончателните уравнения на общата теория на относителността, написани с тензори.
Тук има урок, който не е по математика: да поправиш някого не значи да се скараш с него. „Доказателството ти е грешно“ на Леви-Чивита не завършва със свада: показва на Айнщайн истинска грешка, месеци преди окончателните уравнения, и завършва с приятелство.
Източници: Jeff Miller, „Earliest Known Uses of Some of the Words of Mathematics“, статия TENSOR (Hamilton 1846, Voigt 1898, Ricci-Curbastro и Levi-Civita), в MacTutor: mathshistory.st-andrews.ac.uk/Miller/mathword/t/. Статията на Ричи-Курбастро и Леви-Чивита е „Méthodes de calcul différentiel absolu et leurs applications“, Mathematische Annalen 54, pp. 125–201; томът е датиран 1900 г. и някои каталози го цитират като от 1901 г. Писмата от 1915 г.: Galina Weinstein, „Einstein the Stubborn: Correspondence between Einstein and Levi-Civita“, arxiv.org/abs/1202.4305.
Матео гаси лампата, мислейки за това. Щом на Айнщайн са му казвали „грешно е“, и на него ще му го казват. По-добре днес да му го каже един assert, отколкото банката на 23 декември.
Една истина, за да не те изненада никой
Ако някой ден физик ти каже, че тензорът „не е таблица с числа“, той е прав, от своята гледна точка. Във физиката и в математиката тензорът е кутия с числа, която освен това се подчинява на точни правила, когато завъртиш осите или смениш мерните единици. В програмирането и в ИИ тензор е само подредената кутия. Тази кутия може да съдържа числата на тензор от физиката, но сама по себе си няма вградени нито правилата му, нито смисъла му. Програмистите са взели името назаем от физиката, защото звучи по-добре от „многомерен масив“, какъвто всъщност е.
И един капан в терминологията: на английски броят на измеренията понякога се нарича rank. Не го бъркай с „ранга“ на матрица, който може би си учил по линейна алгебра; това са различни неща.
👉 Ако идваш от бизнес администрацията: числовата част от твоята електронна таблица с листове (без заглавия и бележки) вече е тензор с три измерения, стига всички листове да имат едни и същи колони и едни и същи редове. Доня Лупе го е имала в лаптопа си от години и не го е знаела. Когато на среща някой каже „данните влизат в модела като тензори“, мисли за това: таблици, наредени една върху друга, всички с една и съща форма. А правилото от стъпка 7 важи и за твоите отчети: ако всеки клон ти изпраща листа си с различни колони, никой не може да ги сумира, без първо да ги оправи.
Упражнения към сесия 1
Решенията са в края на тази публикация. Опитай първо; assert ще ти каже дали си познал.
Упражнение 1 — Предвиди, преди да изпълниш. За всяка стойност напиши на хартия колко измерения има, каква е формата ѝ и какво представлява всяко измерение. После го провери с функциите си.
temperatura = 31
calificaciones = [[9, 8, 10], [7, 9, 8], [10, 10, 9], [6, 8, 7]]
foto = [[[255, 0, 0], [0, 255, 0]], [[0, 0, 255], [255, 255, 255]]]
lote = [foto, foto]
Когато вече имаш отговорите си на хартия, впиши ги в тези assert (смени всяко ?) и изпълни:
assert (contar_dimensiones(temperatura), forma(temperatura)) == (?, ?)
assert (contar_dimensiones(calificaciones), forma(calificaciones)) == (?, ?)
assert (contar_dimensiones(foto), forma(foto)) == (?, ?)
assert (contar_dimensiones(lote), forma(lote)) == (?, ?)
print("Ejercicio 1 superado")
Подсказка: calificaciones са 4 ученици с по 3 предмета. foto е изображение от 2 × 2 точки и всяка точка носи три числа: червено, зелено и синьо.
Упражнение 2 — Посочи числото. С papeleria от стъпка 4 напиши индекса, който дава всяка стойност, и го провери с assert:
а) Колко е продал Centro в сряда от химикалки. б) Колко е продал Norte в петък от раници. в) Колко е продал Norte в неделя от тетрадки.
Пример как изглежда едно решено: assert papeleria[0][0][0] == 1200 (Centro, понеделник, тетрадки).
Упражнение 3 — Допиши функцията. Тази версия на forma има две празни места. Попълни ги, без да гледаш стъпка 6, и провери с assert:
def forma2(x):
tamanos = []
while type(x) == list:
tamanos.append(____)
x = ____
return tuple(tamanos)
assert forma2(por_dia) == (7,)
assert forma2(papeleria) == (2, 7, 3)
assert forma2(31) == ()
print("Ejercicio 3 superado")
Упражнение 4 — Твоите собствени данни. Запиши като вложени списъци оценките на 3 ученици по 4 предмета в 3 контролни. Измисли числата. Сам реши реда на измеренията и го запиши в коментар. След това:
а) Напиши assert за формата им.
б) Напиши индекса на втората контролна по третия предмет на първия ученик и го провери с assert срещу оценката, която си измислил на това място.
Това упражнение няма един-единствен верен отговор: зависи от реда, който избереш. Задължително е обаче assert да минава и коментарът ти да казва какво е всяко измерение.
Упражнение 5 — Намери кривата. Една от тези таблици не може да бъде тензор. Намери я на око и го провери с es_rectangular:
a = [[1, 2], [3, 4], [5, 6]]
b = [[1, 2, 3], [4, 5, 6], [7, 8]]
c = [[0], [0], [0]]
Напиши отговорите си в тези assert (смени всяко ? с True или False):
assert es_rectangular(a) == ?
assert es_rectangular(b) == ?
assert es_rectangular(c) == ?
print("Ejercicio 5 superado")
Какво би ти казала forma(b)? Защо не е надеждна?
Чести грешки (и как да ги забележиш)
| Грешка | Как изглежда | Как да я забележиш | Какво да направиш |
|---|---|---|---|
| Броене на индексите от 1 | Искаш петък с por_dia[5] и получаваш събота |
Числото не съвпада с таблицата | Индексите започват от 0: понеделник е 0, петък е 4 |
| Обръщане на реда на индексите | papeleria[4][1][2] вместо papeleria[1][4][2] |
IndexError, защото има само 2 клона |
Редът на индексите е редът на списъците: отвън навътре |
Доверие на forma при крив списък |
forma казва (2, 3) и после един индекс хвърля грешка |
es_rectangular дава False |
Оправи данните, преди да ги използваш; никога не ги допълвай с измислени числа, без да го кажеш |
Подаване на празен списък на forma или на contar_dimensiones |
IndexError: list index out of range вътре във функцията |
Хвърля грешка при [] |
Празната кутия няма първи елемент за отваряне; провери дали данните ти съдържат нещо |
Забравена запетая в (7,) |
assert forma(por_dia) == (7) се проваля, макар че формата е вярна |
assert хвърля грешка при нещо, което „изглежда наред“ |
Кортеж с един елемент има запетая: (7,) |
Преговор за следващата сесия
Сесия 2 започва с тези три въпроса. Отговори на тях, без да поглеждаш урока:
- Как разбираш колко измерения има един набор от данни, без да броиш скоби?
- Какво ти казва формата
(2, 7, 3)и колко числа има общо? - Какво условие трябва да изпълнява един списък от списъци, за да бъде тензор?
🔁 Следващата седмица: Матео оставя списъците и хваща сериозен инструмент. Инсталираш PyTorch и превръщаш книжарницата на доня Лупе в първия си истински тензор. Ще видиш, че PyTorch вече има вградена форма (там се нарича shape) и че отказва да приеме криви списъци.
Същата вечер, преди да затвори лаптопа, Матео отново отвори двата листа. Centro, Norte. Centro, Norte. Същите колони, същите седем дни. И въпреки това в листа на Norte имаше нещо, което не се връзваше. Но за да го види, му трябваше истински инструмент.
Решения (не ги гледай, преди да опиташ)
Упражнение 1.
temperatura 0 () un solo número
calificaciones 2 (4, 3) alumno × materia
foto 3 (2, 2, 3) renglón de puntos × punto × color
lote 4 (2, 2, 2, 3) foto × renglón × punto × color
Редовете assert изглеждат така: (0, ()), (2, (4, 3)), (3, (2, 2, 3)) и (4, (2, 2, 2, 3)).
lote добавя едно измерение в началото: коя снимка. Почти винаги моделите за изображения работят така: получават партиди и дори една-единствена снимка обикновено влиза като партида от една.
Упражнение 2.
assert papeleria[0][2][1] == 700 # a) Centro, miércoles, plumas
assert papeleria[1][4][2] == 200 # b) Norte, viernes, mochilas
assert papeleria[1][6][0] == 200 # c) Norte, domingo, cuadernos
Упражнение 3. Празните места са len(x) и x[0]: запиши дължината на кутията и после я отвори.
Упражнение 4. Един възможен отговор, с реда ученик × предмет × контролна:
# alumno × materia × parcial
parciales = [
[[8, 9, 9], [7, 8, 9], [9, 9, 10], [6, 7, 8]],
[[10, 9, 10], [9, 9, 9], [8, 8, 9], [9, 10, 10]],
[[7, 7, 8], [8, 8, 8], [6, 7, 7], [8, 9, 9]],
]
assert forma(parciales) == (3, 4, 3)
assert parciales[0][2][1] == 9 # primer alumno, tercera materia, segundo parcial
Ако си избрал предмет × ученик × контролна, формата ти е (4, 3, 3), а индексът ти е parciales[2][0][1]. И двата варианта са верни, ако коментарът го казва. Изборът на реда на измеренията е решение за дизайна и в сесия 3 ще видиш защо е важен.
Упражнение 5. Редовете assert са True, False и True. Кривата е b: последният ѝ ред има 2 елемента, а останалите — 3. es_rectangular(b) дава False. forma(b) би казала (3, 3), защото измерва само първия ред, и затова не е надеждна: не проверява останалите.
Какво следва
В сесия 2 оставяш списъците и използваш инструмент, създаден точно за това. Ако искаш да напреднеш, провери дали имаш Python 3.11 или по-нов с python3 --version.
Пиша от онова, което виждаме всеки ден в Hábil, където изграждаме системи за банки, застрахователи и компании в Мексико. Ако в работата ти или в семейния ти бизнес се сблъскаш с подобен проблем, нека поговорим: habil.mx
Предпочитате имейл? Пишете ни на hola@habil.mx