1 / 8 / 0
Регистрация: 31.07.2016
Сообщений: 73

Многократный поиск в результатах запроса к БД

17.08.2016, 07:58. Показов 1918. Ответов 8

Студворк — интернет-сервис помощи студентам
Дано: list of typles, полученный из базы данных с помощью метода cursor.fetchall из пакета mysql.connector.

То есть примерно такая структура данных:
[ {'animal': 'Тигр', 'kind': 'хищник', 'dimension': 'крупный', ...},
{'animal': 'Медведь', 'kind': 'хищник', 'dimension': 'крупный', ...},
{'animal': 'Зубр', 'kind': 'травоядный', 'dimension': 'крупный', ...},
{'animal': 'Мышь', 'kind': 'грызун', 'dimension': 'мелкий', ...}, ...]

В ней надо провести многократный быстрый поиск в определенной колонке с последующим позиционированием на строке, в которой это значение найдено (надо будет проверить значения других ячеек в этой строке).
Пока вижу следующие способы этот поиск организовать:

Python
1
2
3
4
5
6
# Способ 1 - перебор в цикле, пока нужное значение не обнаружится:
 
for n in list1 # внешний цикл, из-за которого поиск будет многократным
    for row in range(mylist):  # mylist - результат применения метода fetchall()
        if n == row.animal:
            # получили нужную строку
Первый способ показался неоптимальным (перебор вложенным циклом всех строк до того, как будет найдено нужное значение), поэтому больше склоняюсь ко второму способу:

Python
1
2
3
4
5
6
7
8
9
10
11
12
#  Способ 2 - сначала выгрузить в список значения колонки, в которой надо будет искать, 
# а сам поиск проводить по этому списку:
 
list2 = []
for row in mylist:  # mylist - результат применения метода fetchall()
    list2.append(str(row.animal))
 
# Затем - поиск с последующим позиционированием:
for n in list1 # внешний цикл, из-за которого поиск будет многократным
    if n in list2:
        i = list2.index(n)
        row = mylist[i] # получили нужную строку
Вроде бы так быстрее будет. Но кода получается больше. А есть ли другие способы?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
17.08.2016, 07:58
Ответы с готовыми решениями:

Многократный поиск в Edit
Привет всем. Вроде прога простая, да не разберусь как доделать её. Нужно организовать поиск подстроки в строке, т.е в едит1 вводим...

Кракозябры в результатах запроса
Здравствуйте! Столкнулся с такой вот проблемой. Есть запрос, который делает выборку из всех полей БД, в том числе из полей типа...

Многократный поиск изображения в изображении
Данная программа ищет только один раз: КлиК Как сделать так, чтобы программа находила поочередно все вхождения, если их 2 и более?

8
Эксперт Python
 Аватар для dondublon
4652 / 2072 / 366
Регистрация: 17.03.2012
Сообщений: 10,182
Записей в блоге: 6
17.08.2016, 08:09
ОМГ....
Вы не указали, что такое list1, list2, mylist и т. д. Не указали, что надо найти. Так что остаётся только предполагать.
Я не работал со связкой python+mysql, но из того, что я вижу, напрямую вытекает такое решение "в лоб":
Python
1
2
for row in mylist:
    if row['animal']== ...
Если же делать не в лоб, то такие вещи (поиск) желательно делать на сервере. Откройте для себя ключевое слово WHERE.
Сервер сам у себя всё, как надо, оптимизирует, он умный. (Но на всякий случай указываю - ему надо помочь, сделать в базе индексы.)
0
1 / 8 / 0
Регистрация: 31.07.2016
Сообщений: 73
17.08.2016, 08:28  [ТС]
Цитата Сообщение от dondublon Посмотреть сообщение
Вы не указали, что такое list1, list2, mylist и т. д.
Насчет mylist - указал:
Цитата Сообщение от somnium Посмотреть сообщение
# mylist - результат применения метода fetchall()
list1 - список, в котором содержатся значения, служащие образцами для поиска
list2 - изначально пустой список, который создается в 4 строке второго примера, далее в него помещаются значения первой колонки результата запроса.
Вот второй пример, теперь - с дополнительными комментариями:
Python
1
2
3
4
5
6
7
8
9
10
11
12
#  Способ 2 - сначала выгрузить в список значения колонки, в которой надо будет искать, 
# а сам поиск проводить по этому списку:
 
list2 = [] # создаем пустой список list2
for row in mylist:  # mylist - результат применения метода fetchall()
    list2.append(str(row.animal)) # заполняем list2 значениями первой колонки результата запроса
 
# Затем - поиск с последующим позиционированием:
for n in list1 # внешний цикл, из-за которого поиск будет многократным
    if n in list2:
        i = list2.index(n)
        row = mylist[i] # получили нужную строку


Цитата Сообщение от dondublon Посмотреть сообщение
такие вещи (поиск) желательно делать на сервере. Откройте для себя ключевое слово WHERE.
Слово WHERE мне известно. Не хотелось бы в цикле бомбардировать сервер десятками запросов, каждый из которых выдернет по одной строчке.
0
Эксперт Python
 Аватар для dondublon
4652 / 2072 / 366
Регистрация: 17.03.2012
Сообщений: 10,182
Записей в блоге: 6
17.08.2016, 09:10
somnium, вы много говорите о вашем коде, КАК вы делаете, но ничего о том, ЧТО вам нужно получить.

Цитата Сообщение от somnium Посмотреть сообщение
пустой список, который создается в 4 строке второго примера, далее в него помещаются значения первой колонки результата запроса.
Было бы понятнее, если бы написали просто - список всех животных (поле animal) из запроса.

Цитата Сообщение от somnium Посмотреть сообщение
if n in list2
Очевидная неоптимальность - поиск в списке, вместо поиска в словаре.

Цитата Сообщение от somnium Посмотреть сообщение
i = list2.index(n)
Причём дважды.

Опишите, что нужно найти. Пока я понял так, что вам надо найти те строки из запроса, где животное находится в списке list1. Сам list1 получаем откуда-то. Задача как раз для WHERE.
Но вы лучше опишите задачу сами.

Цитата Сообщение от somnium Посмотреть сообщение
Слово WHERE мне известно. Не хотелось бы в цикле бомбардировать сервер десятками запросов, каждый из которых выдернет по одной строчке.
А у него работа такая. Бомбардировать десятками запросов ни к чему, конечно, но с чего вы решили, что без этого не обойтись?
Для WHERE есть возможность комбинации условий (OR). Есть возможность ссылаться и делать поиск в других таблицах (IN). Впрочем, тут я уже не силён, давно с sql-ем последний раз работал, но помню, что есть.

Пока я вижу такое лобовое решение без SQL - вместо list1 делаем множество (set), назовём его animals_needed, и вот так:
Python
1
2
3
for row in mylist:
    if row.animal in animals_needed:
        ...
0
2742 / 2341 / 620
Регистрация: 19.03.2012
Сообщений: 8,830
17.08.2016, 09:11
somnium, судя по всему тебе нужно создать хранимую процедуру, которая будет выбирать нужные данные и будет отдвать только то, что тебе нужно или же запрашивай большой кусок данных и парси его в программе. Тут не существует правильного ответа, все зависит от ситуации.
0
1 / 8 / 0
Регистрация: 31.07.2016
Сообщений: 73
17.08.2016, 09:45  [ТС]
Цитата Сообщение от dondublon Посмотреть сообщение
говорите о вашем коде, КАК вы делаете, но ничего о том, ЧТО вам нужно получить.
Хорошо. Попробую сказать, что хотелось бы получить.

Есть список list1 с наименованиями животных, примерно такой:
['Тигр', 'Медведь', 'Лиса', ...], размер - максимум 200 элементов

Есть list of typles (насколько понял - список именованных кортежей) mylist с результатами запроса к БД, структура его такая:
[ {'animal': 'Тигр', 'kind': 'хищник', 'dimension': 'крупный', ...},
{'animal': 'Медведь', 'kind': 'хищник', 'dimension': 'крупный', ...},
{'animal': 'Зубр', 'kind': 'травоядный', 'dimension': 'крупный', ...},
{'animal': 'Мышь', 'kind': 'грызун', 'dimension': 'мелкий', ...}, ...]
строк в mylist - тоже максимум 200.

Задача: в цикле по list1 отыскивать строку mylist с таким же зверем
Зачем это делается:
1) удостовериться, что в mylist есть такой зверь
2) проверить инфу в других ячейках найденной таким образом строчки (typle) из mylist.

Почему я против запроса внутри внешнего цикла по list1 - уже написал. 200 раз долбать базу однострочными запросами - как-то не очень, ведь база лежит на диске, а чтение данных с диска - операция очень медленная.
0
Эксперт Python
 Аватар для dondublon
4652 / 2072 / 366
Регистрация: 17.03.2012
Сообщений: 10,182
Записей в блоге: 6
17.08.2016, 09:56
Цитата Сообщение от somnium Посмотреть сообщение
Задача: в цикле по list1 отыскивать строку mylist с таким же зверем
А почему именно в цикле по list1?

Если без SQL - то можно сделать, к примеру, словарь. Ключ - животное, значение - сколько раз встречается. (На самом деле, это вариация на тему уже предложенного множества.)
Python
1
2
3
animals_needed = {k: 0 for k in list1}
for row in mylist:
    animals_needed[row.animal] += 1
Где останется 0 - значит, такого животного нет.

Как видите, кажущаяся потребность в цикле по list1 отпадает. Думаю, так же отпадёт и "долбание базы однострочными запросами". Будет один красивый запрос. Впрочем, я об этом уже сказал.
1
317 / 268 / 61
Регистрация: 12.10.2011
Сообщений: 434
17.08.2016, 10:27
Кликните здесь для просмотра всего текста
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
CREATE TABLE `table_a` (
  `id` INT NOT NULL,
  `value` VARCHAR(255),
  PRIMARY KEY (`id`)
);
 
CREATE TABLE `table_b`  (
  `id` INT NOT NULL,
  `value` VARCHAR(255),
  PRIMARY KEY (`id`)
);
INSERT INTO table_a VALUES (1, 'A'), (2, 'B'), (3, 'C'), (4, 'D');
INSERT INTO table_b VALUES (1, 'B'), (3, 'C');

table_a
1A
2B
3C
4D

table_b
1B
3C
Кликните здесь для просмотра всего текста
SQL
1
2
3
SELECT * FROM table_a AS res
WHERE (VALUE) NOT IN
(SELECT VALUE FROM table_b);

res
1'A'
4'D'
Один запрос и получите разность двух таблиц - table_a - list_1,table_b - mylist, values - animal.
1
1 / 8 / 0
Регистрация: 31.07.2016
Сообщений: 73
17.08.2016, 10:42  [ТС]
Цитата Сообщение от dondublon Посмотреть сообщение
кажущаяся потребность в цикле по list1 отпадает
Да, действительно так.

Наверное, сделаю первым способом, который вы предложили:
Цитата Сообщение от dondublon Посмотреть сообщение
вместо list1 делаем множество (set), назовём его animals_needed, и вот так:
Python
1
2
3
for row in mylist:
    if row.animal in animals_needed:
        ...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
17.08.2016, 10:42
Помогаю со студенческими работами здесь

Выполнить запрос ODBC из VBA + подсчет строк в результатах запроса
Здравствуйте, Уважаемые форумчане! Подскажите, пожалуйста: есть запрос ODBC, со строкой подключения, все как полагается. Исполняется...

БД об результатах сессии, поиск студентов.
Помогите пожалуйста разобраться! Нужно создать базу данных программы с фактов, которые описывают результаты сессии студентов в виде: ...

Вывод ссылки в результатах поиска (Умный поиск)
Здравствуйте. Как можно реализовать вывод ссылки на скачивание документа в результатах поиска? Используется "Умный поиск" ...

Сведения о результатах сессии: ввод данных, хранение, поиск
ЗАДАНИЕ А 1.Даны сведения о результатах сессии:ФИО студента,названия четырех предметов и оценки,полученные по каждому предмету. ...

Как сделать проверку на наличие данных в результатах запроса "q" и только если они есть выполнить код
Выполнен запрос "q" Есть рабочий код , но он работает только при условии если в запросе "q" есть строки. Если данные...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

Новые блоги и статьи
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11680&d=1772460536 Одним из. . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru