Форум программистов, компьютерный форум, киберфорум
Python
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.78/9: Рейтинг темы: голосов - 9, средняя оценка - 4.78
1 / 8 / 0
Регистрация: 31.07.2016
Сообщений: 73

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

17.08.2016, 07:58. Показов 1867. Ответов 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
Ответ Создать тему
Новые блоги и статьи
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит переходные токи и напряжения на элементах схемы. . . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru