Как отсортировать словарь внутри словаря на основе ключа (в алфавитном порядке) внутреннего словаря в Python - PullRequest
0 голосов
/ 21 мая 2019

Несмотря на то, что я видел много ответов о сортировке словаря из словаря, я не смог настроить решение моей проблемы.

Вот структура моего словаря:

OrderedDict([('2018-11', {'NEOCATE JUNIOR  WITHOUT FLAVOUR 400 gr.': 8}), ('2017-11', {'NEOCATE JUNIOR  WITHOUT FLAVOUR 400 gr.': 804,'ALFAMINO 400 GR.': 4, 'Forticare Orange/Lemon 4 X125ml': 15})])

Внешний словарь имеет в качестве ключа дату в формате год-месяц. Внешний словарь имеет в качестве значения словарь в формате {'название продукта: количество}

Внутренний словарь имеет в качестве ключаназвание продукта Внутренний словарь имеет в качестве значения количество (продукта)

Моя цель состоит в том, чтобы отсортировать мой внешний словарь на основе самой последней даты (самой новой, чтобы быть первой) и моего внутреннего словаряна основе названия продукта в алфавитном порядке.

Другими словами:

OrderedDict([('2018-11', {'NEOCATE JUNIOR  WITHOUT FLAVOUR 400 gr.': 8}),('2017-11',{'ALFAMINO 400 GR.': 4,'Forticare Orange/Lemon 4 X125ml': 15,'NEOCATE JUNIOR  WITHOUT FLAVOUR 400 gr.': 804})])

Сначала идет дата 2018-11, «новее», чем 2017-11 и во внутреннейсловари, если у меня есть несколько записей в качестве словаря с ключом 2017-11, сначала идет ALFAMINO (начинается с A), затем Forticare (начинается с F) и т. д.

Вот мой код:

def warehouse_pending_products(request):
    template_name= 'warehouse/warehouse_pending_products.html'
    pendingOrdersResult={}
    pendingOrdersList=Order.objects.filter(finished=0)
    for order in pendingOrdersList:
        orderYear=order.invoice_date.year
        orderMonth=order.invoice_date.month
        orderDate=str(orderYear)+'-'+str(orderMonth)

        orderProductsWithoutSerials=ProductSerialNumbers.objects.filter(snumber__isnull=True).filter(order=order.id)#order_by('product__name')
        if orderDate in pendingOrdersResult:
            for op in orderProductsWithoutSerials:
                p_name=op.product.name.encode("utf-8")
                if p_name in pendingOrdersResult[orderDate]:


                    pendingOrdersResult[orderDate][p_name]+=1 
                else:

                    pendingOrdersResult[orderDate][p_name]=1
        else:
            if orderProductsWithoutSerials:
                pendingOrdersResult[orderDate]={}
                for op in orderProductsWithoutSerials:
                    p_name=op.product.name.encode("utf-8")
                    if p_name in pendingOrdersResult[orderDate]:
                        pendingOrdersResult[orderDate][p_name]+=1
                    else:
                        pendingOrdersResult[orderDate][p_name]=1


    result = collections.OrderedDict(sorted(pendingOrdersResult.iteritems(), key=lambda (k, v): (pendingOrdersResult[k])))

Мой словарь - pendingOrdersResult.

result = collections.OrderedDict(sorted(pendingOrdersResult.iteritems(), key=lambda (k, v): (pendingOrdersResult[k]))) дает неправильный результат.

enter image description here

Ответы [ 2 ]

2 голосов
/ 21 мая 2019

Похоже, вам нужно вызывать функцию sorted для каждого из «внутренних» словарей в отдельности, а также для «внешнего» словаря.Вы также должны были бы привести свои внутренние словари, чтобы иметь тип OrderedDict, чтобы их можно было сортировать.Вот что я могу придумать, но могут быть более короткие / более идиоматические способы сделать это:

# Sort the outer dictionary by key from high to low
OrderedDict(sorted(d.items(), key=lambda t: t[0], reverse=True))

# Sort the inner dictionaries by key
for item in d.items(): 
    d[item[0]] = OrderedDict(sorted(item[1].items(), key=lambda x: x[0])) 
1 голос
/ 21 мая 2019

Попробуйте следующее (протестировано с python 3.7.1):

import collections

raw    = dict([('2018-11', {'NEOCATE JUNIOR  WITHOUT FLAVOUR 400 gr.': 8}), ('2017-11', {'NEOCATE JUNIOR  WITHOUT FLAVOUR 400 gr.': 804,'ALFAMINO 400 GR.': 4, 'Forticare Orange/Lemon 4 X125ml': 15})])
data   = {key : collections.OrderedDict(sorted(value.items(), key=lambda entry: entry[0])) for key, value in raw.items()}
result = collections.OrderedDict(sorted(data.items(), key = lambda entry: entry[0]))


print(result)

РЕДАКТИРОВАТЬ: с функцией, позволяющей избежать кода "c & p":

import collections

def sort_dict(unsorted):
    return collections.OrderedDict(sorted(unsorted.items(), key=lambda entry: entry[0]))

raw    = dict([('2018-11', {'NEOCATE JUNIOR  WITHOUT FLAVOUR 400 gr.': 8}), ('2017-11', {'NEOCATE JUNIOR  WITHOUT FLAVOUR 400 gr.': 804,'ALFAMINO 400 GR.': 4, 'Forticare Orange/Lemon 4 X125ml': 15})])
result = sort_dict({key : sort_dict(value) for key, value in raw.items()})

print(result)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...