2012-03-07 4 views
1

У меня есть 2 соответствующих списка словарей, items и bookings. Мне нужно определить, какой предмет имеет наименьший заказ.Pythonic способ найти наименьшее количество объектов в списке

Реальный пример находится в базе данных, но ради физические упражнения, рассмотрим эти данные:

from datetime import datetime 

item1 = {'foo1'} 
item2 = {'foo2'} 
items = [item1, item2] 

booking1 = {'Start':datetime(2012,1,1), 'Item':'foo1'} 
booking2 = {'Start':datetime(2012,1,2), 'Item':'foo1'} 
booking3 = {'Start':datetime(2012,1,1), 'Item':'foo2'} 
bookings = [booking1, booking2, booking3] 

Как эффективно определить, какой элемент имеет наименьшее количество заказов? Любая помощь будет принята с благодарностью!

+2

Является ли это SQL база данных? Если это так, то выполнение фильтрации с помощью отдельного запроса select count будет намного быстрее. Если вам нужно вытащить все это на Python, это будет O (n), потому что вы будете * иметь * для итерации по всему списку, в дополнение к неэффективности выбора большего количества данных, чем вам нужно от sql до python. – rob05c

+0

Его NoSQL, но есть «отличительный» эквивалент. Можете ли вы подробнее объяснить, какое значение я должен запросить? Извините, я вас еще не преследую. – MFB

+0

A) Если это в базе данных, выполните работу в базе данных ... Базы данных очень хорошо подходят для заданных проблем, и есть множество похожих вопросов, которые вы можете задать об этих данных, которые легко переводили бы в SQL. B) Это ужасная структура данных для ваших данных. Может ли бронирование иметь не более одного предмета? Почему нет бронирования класса? Если это данные базы данных, вы не используете ORM? – gfortune

ответ

4
from collections import Counter 

# create the counter, from most common to least common. reverse it, and get the first item. 
item, num = Counter(b['Item'] for b in bookings).most_common()[::-1][0] 

Более эффективное (любезно senderle):

from collections import Counter 

c = Counter(b['Item'] for b in bookings) 
item = min(c, key=c.get) 
+0

Спасибо за объяснение .. отлично работает – MFB

+0

В большинстве случаев это, вероятно, ОК - но 'item = min (c, key = c.get)' будет немного более эффективным (O (n)), так как 'most_common' выполняет сортировку (O (n log n)). – senderle

1

Вы можете сделать это легко, хотя и не особенно эффективно, с collections.Counter (мультинабора Пайтона):

import collections 
c = collections.Counter() 

for booking in bookings: 
    c[booking['Item']] += 1 

c.most_common()[:-2:-1] 
[('foo2', 1)] 
+0

Что такое 'n' ???? – MFB

+0

Извините, что это было от моего теста. –

+0

Ах, не беспокойтесь, спасибо – MFB

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