Категоризация списка списков по 1 элементу в python

1

Пример списка списков:

[
["url","name","date","category"]
["hello","world","2010","one category"]
["foo","bar","2010","another category"]
["asdfasdf","adfasdf","2010","one category"]
["qwer","req","2010","another category"]
]

То, что я хочу сделать, это создать словарь → category: [список записей].

Результирующим словарем будет:

{"category" : [["url","name","date","category"]],
"one category" : [["hello","world","2010","one category"],["asdfasdf","adfasdf","2010","one category"]],
"another category" : [["foo","bar","2010","another category"], ["qwer","req","2010","another category"]]}
Теги:
list
sorting
dictionary
map

6 ответов

7
Лучший ответ
dict((category, list(l)) for category, l 
     in itertools.groupby(l, operator.itemgetter(3))

Главное здесь - использование itertools.groupby. Он просто возвращает итерации вместо списков, поэтому есть вызов для list(l), что означает, что если вы в порядке с этим, вы можете просто написать dict(itertools.groupby(l, operator.itemgetter(3)))

  • 1
    Вы можете использовать operator.itemgetter(3) вместо этой лямбды.
  • 0
    @ Игнасио - ты прав, я всегда об этом забываю.
Показать ещё 3 комментария
5
newdict = collections.defaultdict(list)
for entry in biglist:
  newdict[entry[3]].append(entry)
  • 0
    newdict ['категория, которая не существует'] добавляет новый элемент в newdict. Это может быть хорошо с оригинальным постером, но это очень специфическая семантика.
  • 1
    @EOL: он выбирает только те категории, которые находятся в исходном списке, поэтому я не вижу здесь проблемы.
Показать ещё 2 комментария
2

Вариант ответа ghostdog74, который полностью использует семантику setdefaults:

result={}
for li in list_of_lists:
    result.setdefault(li[-1], []).append(li)
1

d = {}
for e in l:
    if e[3] in d:
        d[e[3]].append(e)
    else:
        d[e[3]] = [e]
  • 0
    людям не нравится прямолинейность ...
  • 0
    список забытых не хэш
Показать ещё 1 комментарий
1
list_of_lists=[
["url","name","date","category"],
["hello","world","2010","one category"],
["foo","bar","2010","another category"],
["asdfasdf","adfasdf","2010","one category"],
["qwer","req","2010","another category"]
]
d={}
for li in list_of_lists:
    d.setdefault(li[-1], [])
    d[ li[-1] ].append(li)
for i,j in d.iteritems():
    print i,j
  • 1
    +1, но посмотрите мой ответ, который использует тот факт, что setdefault () возвращает значение.
-3
>>> l = [
... ["url","name","date","category"],
... ["hello","world","2010","one category"],
... ["foo","bar","2010","another category"],
... ["asdfasdf","adfasdf","2010","one category"],
... ["qwer","req","2010","another category"],
... ]
#Intermediate list to generate a more dictionary oriented data
>>> dl = [ (li[3],li[:3]) for li in l ]
>>> dl
[('category', ['url', 'name', 'date']), 
 ('one category', ['hello', 'world', '2010']), 
 ('another category', ['foo', 'bar', '2010']), 
 ('one category', ['asdfasdf', 'adfasdf', '2010']), 
 ('another category', ['qwer', 'req', '2010'])]
#Final dictionary
>>> d = {}
>>> for cat, data in dl:
...   if cat in d:
...     d[cat] = d[cat] + [ data ]
...   else:
...     d[cat] = [ data ]
...
>>> d
{'category': [['url', 'name', 'date']], 
 'one category': [['hello', 'world', '2010'], ['asdfasdf', 'adfasdf', '2010']], 
 'another category': [['foo', 'bar', '2010'], ['qwer', 'req', '2010']]}

Окончательные данные немного отличаются, поскольку я не включил данные в категорию (кажется мне совершенно бессмысленным), но вы можете легко добавить ее, если нужно...

Ещё вопросы

Сообщество Overcoder
Наверх
Меню