Предположим, у меня есть много фруктов разного цвета, например, 24 синих банана, 12 зеленых яблок, 0 голубых ягод клубники и так далее. Я хотел бы организовать их в структуре данных в Python, которая позволяет легко выбирать и сортировать. Моя идея заключалась в том, чтобы поместить их в словарь с кортежами в качестве ключей, например,
{ ('banana', 'blue' ): 24,
('apple', 'green'): 12,
('strawberry','blue' ): 0,
...
}
или даже словари, например,
{ {'fruit': 'banana', 'color': 'blue' }: 24,
{'fruit': 'apple', 'color': 'green'}: 12,
{'fruit': 'strawberry','color': 'blue' }: 0,
...
}
Я хотел бы получить список всех синих фруктов или, например, бананов всех цветов, или отсортировать этот словарь по названию фруктов. Есть ли способы сделать это чисто?
Вполне возможно, что словари с кортежами в качестве ключей - не лучший способ справиться с этой ситуацией.
Все предложения приветствуются!
Ответы:
Лично мне нравится в Python комбинация кортеж-дикт. То, что у вас есть, фактически представляет собой 2d-массив (где x = имя плода и y = цвет), и я обычно сторонник dict кортежей для реализации 2-мерных массивов, по крайней мере, когда что-то вроде
numpy
или база данных не более подходящие . Короче говоря, я думаю, у вас есть хороший подход.Обратите внимание, что вы не можете использовать dicts в качестве ключей в dict без дополнительной работы, так что это не очень хорошее решение.
Тем не менее, вы также должны рассмотреть namedtuple () . Таким образом вы могли сделать это:
Теперь вы можете использовать свой fruitcount dict:
Другие уловки:
Повторяя chmullig, чтобы получить список всех цветов одного фрукта, вам нужно будет отфильтровать ключи, т.е.
источник
name='banana'
?bananas = filter(lambda fruit: fruit.name=='banana', fruits)
илиbananas = [fruit for fruit in fruits if fruit.name=='banana']
. Это один из способов повышения эффективности вложенных dicts; все сводится к тому, как вы планируете использовать данные.count
Лучшим вариантом будет создание простой структуры данных для моделирования того, что у вас есть. Затем вы можете сохранить эти объекты в простом списке и сортировать / извлекать их любым удобным вам способом.
В этом случае я бы использовал следующий класс:
Затем вы можете просто создать экземпляры «Fruit» и добавить их в список, как показано следующим образом:
Простой список
fruits
будет намного проще, менее запутанным и поддерживается лучше.Некоторые примеры использования:
Все приведенные ниже результаты являются результатом выполнения данного фрагмента кода, за которым следует:
Несортированный список:
Отображает:
В алфавитном порядке по названию:
Отображает:
По количеству:
Отображает:
Где цвет == красный:
Отображает:
источник
База данных, dict dicts, словарь списка словарей, именованный кортеж (это подкласс), sqlite, избыточность ... Я не поверил своим глазам. Что еще ?
Да! я думал
Так что, на мой взгляд, списка кортежей достаточно:
результат
источник
Словарь, вероятно, не то, что вам следует использовать в этом случае. Более полнофункциональная библиотека была бы лучшей альтернативой. Наверное, настоящая база данных. Самый простой - sqlite . Вы можете сохранить все это в памяти, передав строку ': memory:' вместо имени файла.
Если вы действительно хотите продолжить этот путь, вы можете сделать это с помощью дополнительных атрибутов в ключе или значении. Однако словарь не может быть ключом к другому словарю, а кортеж может. Документы объясняется, что допустимо. Это должен быть неизменяемый объект, который включает строки, числа и кортежи, содержащие только строки и числа (и другие кортежи, содержащие только эти типы рекурсивно ...).
Вы можете сделать свой первый пример
d = {('apple', 'red') : 4}
, но будет очень сложно запросить то, что вы хотите. Вам нужно будет сделать что-то вроде этого:источник
С ключами в виде кортежей вы просто фильтруете ключи с заданным вторым компонентом и сортируете его:
Сортировка работает, потому что кортежи имеют естественный порядок, если их компоненты имеют естественный порядок.
С ключами как достаточно полноценными объектами вы просто фильтруете по
k.color == 'blue'
.Вы не можете использовать dicts в качестве ключей, но вы можете создать простейший класс, например,
class Foo(object): pass
и добавлять к нему любые атрибуты на лету:Эти экземпляры могут служить в качестве ключей dict, но будьте осторожны с их изменчивостью!
источник
У вас может быть словарь, в котором записи представляют собой список других словарей:
Вывод:
Изменить: как указал Эумиро, вы можете использовать словарь словарей:
Вывод:
источник
Этот тип данных эффективно извлекается из структуры данных, подобной Trie. Это также позволяет выполнять быструю сортировку. Однако эффективность памяти может быть не такой уж большой.
Традиционное дерево хранит каждую букву слова как узел в дереве. Но в вашем случае ваш «алфавит» другой. Вы храните строки вместо символов.
это может выглядеть примерно так:
см. эту ссылку: trie in python
источник
Вы хотите использовать два ключа независимо друг от друга, поэтому у вас есть два варианта:
Сохраните данные с дублированием с помощью двух dicts как
{'banana' : {'blue' : 4, ...}, .... }
и{'blue': {'banana':4, ...} ...}
. Тогда поиск и сортировка станут простыми, но вы должны убедиться, что вы изменяете словари вместе.Сохраните только один dict, а затем напишите функции, которые перебирают их, например:
источник