кластеризация списка словарей в соответствии с конкретными парами ключ / значение

#python #python-3.x #list #dictionary

#python #python-3.x #Список #словарь

Вопрос:

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

Предположим, у меня есть следующий список словарей:

 [  {'a': 0.0, 'b': 0.2, 'c': 0.1},
   {'a': 0.1, 'b': 0.7, 'c': 0.2},
   {'a': 0.0, 'b': 0.2, 'c': 0.3},
   {'a': 0.1, 'b': 0.7, 'c': 0.4},
   {'a': 0.0, 'b': 0.7, 'c': 0.5},
   {'a': 0.0, 'b': 0.7, 'c': 0.6}]
  

и я хочу сгруппировать его в соответствии с ключами a и b. Тогда результатом будет следующий список списка словарей:

  [[{'a': 0.0, 'b': 0.2, 'c': 0.1},
   {'a': 0.0, 'b': 0.2, 'c': 0.3}]

   [{'a': 0.1, 'b': 0.7, 'c': 0.2},
    {'a': 0.1, 'b': 0.7, 'c': 0.4}]

   [{'a': 0.0, 'b': 0.7, 'c': 0.5},
    {'a': 0.0, 'b': 0.7, 'c': 0.6}]]
  

Каков наилучший способ достижения этой цели?

Ответ №1:

Сначала отсортируйте это, затем используйте itertools.groupby .Вы можете попробовать это ниже:

 from itertools import groupby

t = [{'a': 0.0, 'b': 0.2, 'c': 0.1},
     {'a': 0.1, 'b': 0.7, 'c': 0.2},
     {'a': 0.0, 'b': 0.2, 'c': 0.3},
     {'a': 0.1, 'b': 0.7, 'c': 0.4},
     {'a': 0.0, 'b': 0.7, 'c': 0.5},
     {'a': 0.0, 'b': 0.7, 'c': 0.6}]

print([[*j] for i, j in groupby(sorted(t, key=lambda x: (x['a'], x['b'])), key=lambda x: (x['a'], x['b']))])
  

Результат:

 [[{'a': 0.0, 'b': 0.2, 'c': 0.1}, {'a': 0.0, 'b': 0.2, 'c': 0.3}], [{'a': 0.0, 'b': 0.7, 'c': 0.5}, {'a': 0.0, 'b': 0.7, 'c': 0.6}], [{'a': 0.1, 'b': 0.7, 'c': 0.2}, {'a': 0.1, 'b': 0.7, 'c': 0.4}]]
  

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

 from itertools import groupby

def group_by(*args):
    return [[*j] for i, j in groupby(sorted(t, key=itemgetter(*args)), key=itemgetter(*args))]


t = [{'a': 0.0, 'b': 0.2, 'c': 0.1},
     {'a': 0.1, 'b': 0.7, 'c': 0.2},
     {'a': 0.0, 'b': 0.2, 'c': 0.3},
     {'a': 0.1, 'b': 0.7, 'c': 0.4},
     {'a': 0.0, 'b': 0.7, 'c': 0.5},
     {'a': 0.0, 'b': 0.7, 'c': 0.6}]

print(group_by('a', 'b'))
  

Комментарии:

1. @cyrus Вы могли бы использовать *args для их получения и использовать понимание списка для создания фильтра. Я обновил свой ответ.