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

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

17.08.2016, 07:58. Показов 1934. Ответов 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
4653 / 2073 / 366
Регистрация: 17.03.2012
Сообщений: 10,183
Записей в блоге: 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
4653 / 2073 / 366
Регистрация: 17.03.2012
Сообщений: 10,183
Записей в блоге: 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
4653 / 2073 / 366
Регистрация: 17.03.2012
Сообщений: 10,183
Записей в блоге: 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
Ответ Создать тему
Новые блоги и статьи
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
Подстановка значения реквизита справочника в табличную часть документа
Maks 10.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: при выборе сотрудника (справочник Сотрудники) в ТЧ документа. . .
Очистка реквизитов документа при копировании
Maks 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях. Задача: при копировании документа очищать определенные реквизиты и табличную. . .
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели 8ATzM_2aurI
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2. Задача: запретить редактирование документа, если он открыт у другого пользователя. / / . . .
Система безопасности+живучести для сервера-слоя интернета (сети). Двойная привязка.
Hrethgir 08.04.2026
Далее были размышления о системе безопасности. Сообщения с наклонным текстом - мои. А как нам будет можно проверить, что ссылка наша, а не подделана хулиганами, которая выбросит на другую ветку и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru