2015-02-27 2 views
1

У меня есть словарь словарей. В этих подзаголовках у меня есть два ключа - ui_section и section_order - которые определяют, отображается ли value этого подзадача в определенной части пользовательского интерфейса, и если да, то в каком порядке он появляется. Мой словарь выглядит следующим образом:Сортировать список по индексам другого списка?

MASTER_DICT = { 
    'key1': {'ui_section':[1,2],'section_order':1, 'value': 'key1'}, 
    'key2': {'ui_section':[1],'section_order':2, 'value': 'key2'}, 
    'key3': {'ui_section':[1,2],'section_order':3, 'value': 'key3'}, 
    'key4': {'ui_section':[1],'section_order':4, 'value': 'key4'}, 
    'key5': {'ui_section':[1],'section_order':5, 'value': 'key5'}, 
    'key6': {'ui_section':[1],'section_order':6, 'value': 'key6'}, 
    'key7': {'ui_section':[1],'section_order':7, 'value': 'key7'}, 
    'key8': {'ui_section':[1],'section_order':8, 'value': 'key8'}, 
    'key9': {'ui_section':[1],'section_order':9, 'value': 'key9'}, 
} 

ui_section список возможных разделов ключ может появиться в I определить это с помощью следующего кода:.

def show_section_ui(master_dict, section=None): 
    if section: 
     ui_sections = [] 
     # Find the keys that are part of this section 
     for k in master_dict.keys(): 
      try: 
       if section in master_dict[k]['ui_section']: 
        ui_sections.append(master_dict[k]) 
      except AttributeError: 
       pass 
     # Order the keys by sort order 
     ui_sections.sort(key=lambda x: x['section_order']) 

     return ui_sections 
    else: 
     return None 

Эта часть кода работает. Выход ниже показывает, что порядок является правильным для обеих секций 1 и 2.

>>> pprint.pprint(show_section_ui(MASTER_DICT, 1)) 
[{'section_order': 1, 'ui_section': [1,2], 'value': 'key1'}, 
{'section_order': 2, 'ui_section': [1], 'value': 'key2'}, 
{'section_order': 3, 'ui_section': [1,2], 'value': 'key3'}, 
{'section_order': 4, 'ui_section': [1], 'value': 'key4'}, 
{'section_order': 5, 'ui_section': [1], 'value': 'key5'}, 
{'section_order': 6, 'ui_section': [1], 'value': 'key6'}, 
{'section_order': 7, 'ui_section': [1], 'value': 'key7'}, 
{'section_order': 8, 'ui_section': [1], 'value': 'key8'}, 
{'section_order': 9, 'ui_section': [1], 'value': 'key9'}] 


>>> pprint.pprint(show_section_ui(MASTER_DICT, 2)) 
[{'section_order': 1, 'ui_section': [1,2], 'value': 'key1'}, 
    {'section_order': 3, 'ui_section': [1,2], 'value': 'key3'}] 

Моя проблема заключается в том, что section_order необходимо иметь порядка сортировки в ui_section. Например, в приведенных выше выводах, в разделе 2, я хотел бы, чтобы key3 был первым. Моя первоначальная мысль состояла в том, чтобы сделать section_order список. Но, я не уверен, как настроить эту линию, чтобы правильно учитывать в списке (и выбрать правильный индекс для сортировки тогда)

ui_sections.sort(key=lambda x: x['section_order']) 

Мое намерение состояло в том, чтобы сделать что-то вроде этого:

MASTER_DICT = { 
    'key1': {'ui_section':[1,2],'section_order':[1,2], 'value': 'key1'}, 
    'key2': {'ui_section':[1],'section_order':[2], 'value': 'key2'}, 
    'key3': {'ui_section':[1,2],'section_order':[3,1], 'value': 'key3'}, 
} 

Как мне такой вывод:

>>> pprint.pprint(show_section_ui(MASTER_DICT, 2)) 
[{'section_order': [3,1], 'ui_section': [1,2], 'value': 'key3'}, 
{'section_order': [1,2], 'ui_section': [1,2], 'value': 'key1'}] 

Как можно отсортировать по ui_section и соответствующий индекс в ключе?

ответ

1

не имеют хороший один линии изменения кода для вас, но вы можете заменить строку, вы должны:

ui_sections.sort(key=lambda x: x['section_order']) 

С этим:

sort_orders = [] 
for s in ui_sections: 
    ndx = s['ui_section'].index(section) 
    # This next line makes the assumption that you ALWAYS have a section_order 
    # for every ui_section listed. If not, you'll get an IndexError 
    sort_orders.append(s['section_order'][ndx]) 

    # Magic happens here   
    sorted_sections = [x for y, x in sorted(zip(sort_orders,ui_sections))] 
    return sorted_sections 

Выход:

>>> pprint.pprint(show_section_ui(MASTER_DICT, 2)) 
[{'section_order': [3, 1], 'ui_section': [1, 2], 'value': 'key3'}, 
{'section_order': [1, 2], 'ui_section': [1, 2], 'value': 'key1'}] 

>>> pprint.pprint(show_section_ui(MASTER_DICT, 1)) 
[{'section_order': [1, 2], 'ui_section': [1, 2], 'value': 'key1'}, 
{'section_order': [2], 'ui_section': [1], 'value': 'key2'}, 
{'section_order': [3, 1], 'ui_section': [1, 2], 'value': 'key3'}, 
{'section_order': [4], 'ui_section': [1], 'value': 'key4'}, 
{'section_order': [5], 'ui_section': [1], 'value': 'key5'}, 
{'section_order': [6], 'ui_section': [1], 'value': 'key6'}, 
{'section_order': [7], 'ui_section': [1], 'value': 'key7'}, 
{'section_order': [8], 'ui_section': [1], 'value': 'key8'}, 
{'section_order': [9], 'ui_section': [1], 'value': 'key9'}] 

Добавление key8 к второй ui_section в положении 3, и key7 в положении 4:

[{'section_order': [3, 1], 'ui_section': [1, 2], 'value': 'key3'}, 
{'section_order': [1, 2], 'ui_section': [1, 2], 'value': 'key1'}, 
{'section_order': [8, 3], 'ui_section': [1, 2], 'value': 'key8'}, 
{'section_order': [7, 4], 'ui_section': [1, 2], 'value': 'key7'}] 

Это использует this ответ. Во-первых, хотя, он находит индекс, что секция указана в ui_section:

ndx = s['ui_section'].index(section) 

Значение в этом месте затем добавляется к списку sort_orders. Обратите внимание, что предоставленный код не проверяет ошибку, что это действительно (т. Е. Если у вас нет значения для второй позиции), и будет вызывать IndexError, если это не так.

sort_orders.append(s['section_order'][ndx]) 

Следующая он застегивает два списка вместе с тем, что у вас есть список кортежей, содержащих порядок сортировки и словарь раздел.

[(3, {'ui_section': [1, 2], 'section_order': [8, 3], 'value': 'key8'}), 
(1, {'ui_section': [1, 2], 'section_order': [3, 1], 'value': 'key3'}), 
(2, {'ui_section': [1, 2], 'section_order': [1, 2], 'value': 'key1'}), 
(4, {'ui_section': [1, 2], 'section_order': [7, 4], 'value': 'key7'}) 
] 

Затем мы сортируем, основываясь на первой позиции в кортеже. Затем мы разархивируем его и отбрасываем отсортированную информацию. Все это происходит в этой строке:

sorted_sections = [x for y, x in sorted(zip(sort_orders,ui_sections))] 
2

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

Нам нужен itertools.count(), который представляет собой бесконечный диапазон увеличения, используемый для применения индекса.

import itertools 

они должны быть отсортированы по «значение»

>>> values = [{"name": "A", "value": 10}, 
       {"name": "B", "value": 8}, 
       {"name": "C", "value": 9}] 

они находятся в том же порядке ввода в качестве values, и должны быть отсортированы в том же порядке,

>>> to_sort = [{"name": "A", "payload": "aaa"}, 
       {"name": "B", "payload": "bbb"}, 
       {"name": "C", "payload": "ccc"}] 

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

>>> zip(values, itertools.count()) 

[({'name': 'A', 'value': 10}, 0), 
({'name': 'B', 'value': 8}, 1), 
({'name': 'C', 'value': 9}, 2)] 

Теперь сортировать по ключевому значению. x[0] - это получить первый элемент пары (объект).

>>> sorted(zip(values, itertools.count()), key=lambda x: x[0]["value"]) 
[({'name': 'B', 'value': 8}, 1), 
({'name': 'C', 'value': 9}, 2), 
({'name': 'A', 'value': 10}, 0)] 

Теперь извлеките индексы из пар, чтобы вернуть новый порядок исходных индексов.

>>> map(lambda x: x[1], 
     sorted(zip(values, itertools.count()), 
       key=lambda x: x[0]["value"])) 
[1, 2, 0] 

Теперь используйте эти индексы для отображения списка to_sort и получения элементов по этим индексам.

>>> map(lambda i: to_sort[i], 
     map(lambda x: x[1], 
      sorted(zip(values, itertools.count()), 
        key=lambda x: x[0]["value"]))) 

[{'name': 'B', 'payload': 'bbb'}, 
{'name': 'C', 'payload': 'ccc'}, 
{'name': 'A', 'payload': 'aaa'}] 

Я надеюсь, что ответит на ваш вопрос. Это означает изменение MASTER_DICT, чтобы быть списком, но я думаю, что это лучшее представление для него в любом случае.

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