Наборы - это просто наборы элементов, порядок не такой, как у списков.
Я бы написал так: создать словарь, а затем, когда мы преобразуем его в список, мы можем отсортировать его в соответствии с порядком ввода.
fruitlist = [('Vendor A', 'Apples'),
('Vendor B', 'Apples'),
('Vendor C', 'Bananas'),
('Vendor A', 'Grapes'),
('Vendor A', 'Bananas'),
('Vendor B', 'Oranges')]
vendors = {}
for vendor, fruit in fruitlist:
vendors.setdefault(vendor, []).append(fruit)
ordered_fruitlist_vendors = [t[0] for t in fruitlist]
vendors_list = [[k, tuple(v)] for k,v in vendors.items()]
vendors_list.sort(key=lambda t: ordered_fruitlist_vendors.index(t[0]))
, что дает vendors_list
как:
[['Vendor A', ('Apples', 'Grapes', 'Bananas')], ['Vendor B', ('Apples', 'Oranges')], ['Vendor C', ('Bananas',)]]
Однако я сомневаюсь, что преобразование аккуратного словаря в этот неуклюжий список из двухэлементных списков с кортежами необходимо. Конечно, вы хотите иметь возможность получить фрукты у продавца за O(1)
время с vendors['Vendor A']
вместо того, чтобы перебирать этот список, который будет O(n)
? В любом случае, оба метода теперь являются опциями!
Объяснение setdefault
.
Метод setdefault
словаря принимает два параметра - ключ и значение. Если ключ уже присутствует в словаре, возвращается текущее значение, в противном случае ключ создается со значением, переданным в функцию, и возвращается это значение.
Например:
>>> d = {1:2}
>>> d.setdefault(1,3)
2
>>> d
{1: 2}
>>> d.setdefault(3,4)
4
>>> d
{1: 2, 3: 4}
Итак, хитрый трюк, использующий этот метод, - установить ключ в пустой список ([]
). Тогда, если у нас еще нет этого ключа (в нашем случае этот поставщик еще не был замечен), тогда возвращается пустой список. В противном случае мы получаем ссылку на список, который содержит все плоды этого вендора, которые мы видели до сих пор. Прелесть в том, что мы можем просто добавить наш новый фрукт в независимо от того, возвращается ли , и либо будет создана новая запись для этого поставщика, и добавлен новый фрукт, либо, если этот продавец уже существует, мы просто добавим ранее созданный список.
Это означает, что нам нужно перебирать fruitlist
только один раз, чтобы решение было эффективным.
Еще один пример метода в действии со списками:
>>> d = {}
>>> d.setdefault(1, []).append(2)
>>> d
{1: [2]}
>>> d.setdefault(1, []).append(3)
>>> d.setdefault(1, []).append(4)
>>> d
{1: [2, 3, 4]}
>>> d.setdefault(2, []).append(3)
>>> d.setdefault(2, []).append(3)
>>> d.setdefault(2, []).append(3)
>>> d
{1: [2, 3, 4], 2: [3, 3, 3]}