Skatilsya, в приведённом примере просто используется указатель. Простейший вид массива в Си устроен именно так - как указатель на нулевой элемент массива, его начало. Поэтому и указатель можно использовать как массив. По сути, M[i] будет преобразовываться в обращение к адресу памяти M + i * sizeof(float), и по этому адресу будет читаться/записываться float.
Как я уже писал, можно сделать двухмерный массив двумя способами. Первый - "честный", через двойной указатель: float** M;
Тогда у тебя будет массив указателей на строки, каждый из которых можно интерпретировать как одномерный массив (строку float'ов). Плюс - работаешь с массивом как обычно, M[row][col]. Кроме того, строки в массиве могут иметь разную длину (если это надо).
Минус в том, что такой массив утомительно создавать/уничтожать - тебе придётся сначала создать массив указателей, потом инициализировать каждый элемент адресом массива-строки. Уничтожение в обратном порядке. Кроме того, массив может располагаться в памяти в разнобой - иногда это недопустимо, например, для изображений.
Альтернативно, делаешь одномерный массив, как у тебя, просто сам пересчитываешь индексы в индекс этого массива. idx = row * W + col, где W - число столбцов в массиве, т.е. длина одной строки. А потом обращаешься к M[idx]. Тут обращение сложнее, но зато создавать/уничтожать массив проще, и он точно будет идти в памяти подряд.
Такими темпами ты будешь очень долго разбираться. Потому что сдаётся мне, ты хотел сказать типа данных "массив". Всё же терминологию нужно запоминать, проще гуглить будет.
Ну и да - есть там массивы, просто нужно понимать их специфику. Вообще за этим лучше в учебник.
SAVA_TRV, значит, ты что-то намудрил, или структура проекта у тебя отличается от заявленной в вопросе.
Я только что проверил описанную мной выше схему, где file2 импортирует file1, а main - file2.
Всё работает.
Дмитрий, это типа вообще не имеет смысла. Если у тебя одномерный массив, как ты к нему обратишься по двум индексам? Нужно либо делать нормальный двухмерный, либо (если прям очень-очень нужно именно одномерный) пересчитывать два индекса в один самостоятельно.
PLGF, ну да. Одна из вещей, которую стоит осознать: в питоне вообще всё - оператор. Т.е. class - оператор объявления класса, def - оператор объявления функции, в том же смысле что if - условный оператор а while - оператор цикла. Тогда проще привыкнуть к мысли, что модуль выполняется при импорте целиком.
Концепция направлена исключительно на простые запросы.
define "простые". Для обычного человека "количество новых клиентов за 2023 год" - это просто, но под этим может скрываться "количество клиентов, у которых нет успешно завершенных заказов ранее 2023 года, но есть успешно завершенные заказы в 2023 году".
При такой структуре проекта прекрасно прокатывает from folder1.file1 import *
внутри file2.py
Вот если folder1 и folder2 не в корне проекта, дело усложняется.
Rehaust, правила сайта тоже принял не читая? Так прочитай.
Там написано, что код в вопросе надо оборачивать блоком <code> <\code>. Этот блок можно вставить кнопкой </>.
Gisem, если фреймворк для бота синхронный, ты не сможешь просто "прикрутить сбоку" асинхронность.
Тебе нужно с самого начала писать код на асинхронном фреймворке, типа aiogram или подобном.
1. Format your code according to this site's rules, using </> button. Right now it's unreadable.
2. English clearly isn't your primary language, so don't bother with trying to use it to seem smarter. It never works.
Everything_is_bad, ИМХО с sqlite лучше синхронно работать, так как винда не умеет в асинхронную работу с файлами в стиле unix. Если я верно понял, aiosqlite тупо закидывает операции с базой в отдельный рабочий поток. Учитывая типичный ничтожный объём данных, это чистый оверхед без сколь-нибудь значительного выигрыша с точки зрения asyncio.
Everything_is_bad, ну имя метода recognize_google() наводит на мысли о том, что задача скорее IO-bound, только выполнена синхронно. А так да, не всякая CPU-bound задача не дружит с потоками - только если она выполнена в питоновском коде. Если задача оформлена как сишное расширение, то она не особо дергает GIL, по идее.
M[i]
будет преобразовываться в обращение к адресу памятиM + i * sizeof(float)
, и по этому адресу будет читаться/записываться float.Как я уже писал, можно сделать двухмерный массив двумя способами. Первый - "честный", через двойной указатель:
float** M;
Тогда у тебя будет массив указателей на строки, каждый из которых можно интерпретировать как одномерный массив (строку float'ов). Плюс - работаешь с массивом как обычно, M[row][col]. Кроме того, строки в массиве могут иметь разную длину (если это надо).
Минус в том, что такой массив утомительно создавать/уничтожать - тебе придётся сначала создать массив указателей, потом инициализировать каждый элемент адресом массива-строки. Уничтожение в обратном порядке. Кроме того, массив может располагаться в памяти в разнобой - иногда это недопустимо, например, для изображений.
Альтернативно, делаешь одномерный массив, как у тебя, просто сам пересчитываешь индексы в индекс этого массива.
idx = row * W + col
, где W - число столбцов в массиве, т.е. длина одной строки. А потом обращаешься к M[idx]. Тут обращение сложнее, но зато создавать/уничтожать массив проще, и он точно будет идти в памяти подряд.