2015-06-04 2 views
3

Скажет, у меня естьPython `dict` индексируется кортежем: Получение куска пирога

my_dict = { 
    ("airport", "London"): "Heathrow", 
    ("airport", "Tokyo"): "Narita", 
    ("hipsters", "London"): "Soho" 
} 

Что не является эффективным (без сканирования всех ключей), но элегантный способа получить все аэропорты из этого словарь, то есть ожидаемый выход ["Heathrow", "Narita"]. В базах данных, которые могут индексировать кортежами, обычно это можно сделать что-то вроде

airports = my_dict.get(("airport",*)) 

(но обычно только с «звезды» сидит на правых местах в кортеже, так как индекс обычно хранится только в одном заказе) ,

Поскольку я предполагаю, что Python индексирует словарь с помощью ключей кортежа аналогичным образом (используя встроенный порядок ключей), я полагаю, что может быть метод, который я мог бы использовать для обрезки индекса таким образом?

Edit1: Добавлен ожидаемый результат

Edit2: Удалены последняя фраза. Добавлен «(без сканирования всех ключей)» к условиям, чтобы сделать его более понятным.

+1

Что вы ожидаете выход. Можете ли вы опубликовать это тоже. Ваш вопрос путается – csharpcoder

+0

Спасибо, просто добавил. –

+1

используйте словарь словарей. –

ответ

4

Путь ваши данные в настоящее время организовано не позволяет эффективно поиск - по существу, вы должны сканировать все ключи.

Словари - это хеш-таблицы за кулисами, и единственный способ получить доступ к значению - получить хэш ключа - и для этого вам нужен ключ .

Используйте вложенную иерархию, как это, так что вы можете сделать прямой O (1) поиск:

my_dict = { 
    "airport": { 
    "London": "Heathrow", 
    "Tokyo": "Narita", 
    }, 
    "hipsters": { 
    "London": "Soho" 
    } 
} 
1

То, что я хотел бы избежать, если возможно, состоит в том, чтобы пройти через все словарные ключи и отфильтровать их.

Почему? Как вы думаете, почему Python выполняет эквивалент полного сканирования в базе данных? Фильтрация словаря не означает последовательного сканирования.

Python:

[value for key, value in my_dict.items() if key[0] == "airport"] 

Выход:

['Narita', 'Heathrow'] 
+1

Спасибо. 'Фильтрация словаря не означает последовательного сканирования его.' Не могли бы вы расширить это? Мне любопытно, как python реализует это, если не полностью сканировать. Автоматически ли она оптимизируется, если я фильтрую только первую часть ключа? Что делать, если я делаю '[значение для ключа, значение в my_dict.items(), если ключ [1] ==" Tokyo "]', будет *, что * приведет к последовательной проверке? –

+0

@ MichelMüller: проверьте, как «если» Токио «в ключе» –

+2

«последовательное сканирование» - ну, вот что делает ваш код. –

3

Проверить "airport" присутствует в каждом ключе в словаре.

Demo:

>>> [value for key, value in my_dict.items() if "airport" in key] 
['Narita', 'Heathrow'] 
>>> 

Да, Вложенные словарь будет лучшим вариантом.

>>> my_dict = { 
... "airport": { 
...  "London": "Heathrow", 
...  "Tokyo": "Narita", 
... }, 
... "hipsters": { 
...  "London": "Soho" 
... } 
... } 
>>> 
>>> if "airport" in my_dict: 
...  result = my_dict["airport"].values() 
... else: 
...  result = [] 
... 
>>> print result 
['Heathrow', 'Narita'] 
>>> 
+2

В принципе, тот же комментарий здесь - разве это не последовательное сканирование по всем клавишам? –

+0

@ MichelMüller: Думаю, что нет. Создайте словарь словаря, как вы растягиваете в своем комментарии. –

Смежные вопросы