группировка списка объектов по определенной характеристике

#list #dictionary #python #list-comprehension

#Список #словарь #python #список-понимание

Вопрос:

У меня есть список объектов (строк в этом примере), которые я хочу классифицировать в соответствии с определенной характеристикой, возвращаемой функцией.

Например, рассмотрим следующий список:

 ['sky', 'ocean', 'grass', 'tomato', 'leaf']
  

и функция color(item) , которая возвращает цвет переданной ей строки, например, color('sky') возвращает 'blue' . Теперь я хочу преобразовать список в словарь или список списков, который группирует элементы в соответствии с их цветом / значением, возвращаемым функцией. Возможный результат будет выглядеть следующим образом:

 { 
    'blue': ['sky', 'ocean'],
    'green': ['grass', 'leaf'],
    'red': ['tomato']
}
  

Меня не волнует сам ключ, только то, что элементы сгруппированы соответствующим образом, поэтому вложенные списки тоже были бы хороши. Просто пытаюсь сделать это питоническим способом 🙂

Ответ №1:

Я думаю, что я бы подошел к этому вопросу следующим образом:

 from collections import defaultdict

D = defaultdict(list)

a = ['sky', 'ocean', 'grass', 'tomato', 'leaf']

for item in a:
  D[color(item)].append(item)
  

Это дает вам словарь списков, разделенных по цветам, который содержит элементы для этой категории.

Ответ №2:

 a = ['sky', 'ocean', 'grass', 'tomato', 'leaf']

sa = {}
for x in a:
  key = color(x)
  if key in sa:
    sa[key].append(x)
  else:
    sa[key] = [x]
  

Не уверен, насколько это по-питоновски, но это довольно понятно. В достаточно поздних версиях Python вы можете использовать словарь по умолчанию, чтобы сделать ядро цикла более чистым.

Ответ №3:

Небольшая модификация решения, предложенного ‘unwind’:

 a = ['sky', 'ocean', 'grass', 'tomato', 'leaf']

def color(x):
    # dummy hash function for demo
    return len(x)

color_map = {}

for x in a:
    key = color(x)
    color_map.setdefault(key,[]).append(x)

print color_map
  

Приведенный выше пример кода выводит:

{3: ['небо'], 4: ['лист'], 5: ['океан', 'трава'], 6: ['помидор']}