Похоже, вы пытаетесь реализовать таблицу базы данных.Это наиболее естественно реализовано как набор диктов.(Но есть библиотеки с более эффективными реализациями, такими как sqlite и pandas)
table = {
dict(zip(('SerialNo', 'Name', 'Food'), row))
for row in [
(1, 'John', 'Apple'),
(2, 'Bill', 'Orange'),
(3, 'Josh', 'Apple'),
]
}
Вы можете выполнять свои запросы как списки.
# SerialNo s where Food='Apple'
[row['Food'] for row in table if row['Food'] == 'Apple']
# Name where Food='Apple'
[row['Name'] for row in table if row['Food'] == 'Apple']
# Food where Name='Bill'
[row['Food'] for row in table if row['Name'] == 'Bill']
# Get the all stored data (SerialNo, Name, Food)
table
Возможны более сложные запросы.Для больших таблиц вы можете сделать запросы более эффективными, заранее создав внешний индекс, как механизм базы данных.Используйте словарь с вашими ключами поиска и указывайте их на свои строки в наборе таблиц.
name_index = {row['Name']: row for row in table}
name_index['John'] # {'SerialNo': 1, 'Name': 'John', 'Food': 'Apple'}
Вы также можете попробовать набор именованных кортежей в качестве строк таблицы вместо слов для большей эффективности.Это также позволяет использовать точечную запись для доступа к ячейке.
Новое требование:
Привет, я не могу использовать dict.Я предпочитаю создавать эту функцию для целей обучения.
ОК, поэтому реализуйте обычную хеш-таблицу и используйте ее вместо родного языка Python.Если вам нужно несколько индексов, используйте несколько хеш-таблиц, как указано выше.
Но, у меня есть дубликаты Пищевая ценность, как индексировать ее?
Подумайте, что мог бы вернуть запрос, использующий этот индекс.Это ряд строк, которые используют эту еду вместо одного ряда, верно?Так что это то, что вы используете в качестве значения для поиска в хеш-таблице индекса.
{food: {row for row in table if row['Food']==food}
for food in {row['Food'] for row in table}}
Возможно, вы могли бы сделать это немного более эффективно с помощью цикла for.
food_index = {}
for row in table:
food_index.setdefault(row['Food'], set()).add(row)
Это можетупростите вашу логику, если уникальные индексы также возвращают наборы строк вместо одной строки.(В этом случае набор будет содержать одну строку.)
name_index = {row['Name']: {row} for row in table}
Я все еще использую дикты, чтобы продемонстрировать подход кратко, но нет никаких причин, по которым вы не могли бы реализовать все эти функции самостоятельно,Даже понимание может быть сделано с помощью выражения генератора внутри вызова функции, например,
{k:v for k, v in foo}
dict((k, v) for k, v in foo)
Эти две строки выше функционально эквивалентны.Конечно, если foo
уже содержит пары (например, результат вызова zip
), его можно упростить до
dict(foo)
Вместо * можно использовать собственный класс хеш-таблицы.1044 *.
Ваша реализация мультикарты может создавать и сохранять эти индексы при инициализации и соответствующим образом обновлять наборы строк в каждом индексе при добавлении или удалении строк из таблицы.Отключение dict строки может сделать недействительными индексы, поэтому может быть более целесообразным сделать каждую строку неизменным типом, например, именованным кортежем и т. П. (Если необходимо, реализуйте его самостоятельно).Затем изменение строки в таблице - это просто добавление новой строки и удаление старой.