группировать список словаря по значению кортежа - PullRequest
0 голосов
/ 29 мая 2020

Я попытался решить эту проблему с помощью списков, itemgetter и groupby, но мне это не кажется близким. Учитывая этот тип списка dict:

test_list = [{'text': "Hi",'bbox': (0,0)},
          {'text': "There.",'bbox': (1,0)},
          {'text': "Im",'bbox': (0,1)},
          {'text': "John.",'bbox': (1,1)},
         ]

Я ищу этот результат:

[['Hi',"There."],['Im','John.']]

Где значения 'text' группируются вторым элементом кортежа в 'bbox '. Спасибо

Ответы [ 3 ]

3 голосов
/ 29 мая 2020

Вы можете легко выполнить эту задачу, используя defaultdict из collections модуля:

from collections import defaultdict


test_list = [
    {'text': "Hi",'bbox': (0,0)},
    {'text': "There.",'bbox': (1,0)},
    {'text': "Im",'bbox': (0,1)},
    {'text': "John.",'bbox': (1,1)},
]

out = defaultdict(list)
for k in test_list: 
    out[k['bbox'][1]].append(k['text'])

# print(out.values())
print(list(out.values()))
# [['Hi', 'There.'], ['Im', 'John.']]

Обновление:

Вы можете также используйте объект по умолчанию Python dict, как в этом примере:

out = {}
for k in test_list:
    key, value = k['bbox'][1], k['text']
    if key in out:
        out[key].append(value)
    else:
        out[key] = [value]

print(list(out.values()))
# [['Hi', 'There.'], ['Im', 'John.']]
2 голосов
/ 29 мая 2020

А groupby подход. Одна строка, но не очень удобочитаемая.

from itertools import groupby

test_list = [
    {'text': "Hi",'bbox': (0,0)},
    {'text': "There.",'bbox': (1,0)},
    {'text': "Im",'bbox': (0,1)},
    {'text': "John.",'bbox': (1,1)},
]

result = [[s['text'] for s in groups] for _, groups in groupby(test_list, key=lambda x: x['bbox'][1])]

print(result)

Обратите внимание, что это работает, потому что ввод уже правильно отсортирован, но если бы это не было, его нужно было бы сначала отсортировать перед вызовом groupby.

0 голосов
/ 29 мая 2020

Извините за двойной пост, пока не могу комментировать. В случаях, когда элементы еще не отсортированы, безбиблиотечное решение @Chiheb Nexus будет содержать правильные группы, но не обязательно в правильном порядке. Поскольку критерий порядка отбрасывается в операции, это может быть неблагоприятным, но вопрос не уточняет этого. То же самое относится к порядку элементов внутри каждой группы. Упорядочивание словаря out по ключу перед преобразованием в список упорядочит группировки, а сохранение первой записи атрибута bbox позволит сортировать каждую группировку по этой записи.

...