创建一个包含字典列表的一个键的列表。

4

这应该是一个简单的问题,但因为我不太熟悉Python,所以我还没有完全弄清楚它的工作原理。 我有以下csv文件

name        ; type
apple       ; fruit
pear        ; fruit
cucumber    ; vegetable
cherry      ; fruit
green beans ; vegetable

我想要实现的是列出所有不同类型及其对应的名称,例如:
fruit: apple, pear, cherry
vegetable: cucumber, green beans

使用csv.DictReader读取csv文件后,我可以生成一个字典列表,保存在变量alldata中。
alldata = 
[
  {'name':'apple', 'type':'fruit'},
  {'name':'pear',  'type':'fruit'},
  ...
]

现在我需要从alldata中获取所有不同类型值的列表。
types = ??? #it should contain [fruit, vegetable]

这样我就可以迭代列表并提取与这些类型相对应的名称:

foreach type in types
  list_of_names = ??? #extract all values of alldata["type"]==type and put them in a new list
  print type + ': ' + list_of_names

有人知道如何实现这个吗?


1
set(row["type"] for row in alldata) - michaelmeyer
3个回答

5

您可以使用列表推导式来解决这个问题:

types = set([data['type'] for data in  alldata])

list_of_name = [data['name'] for data in alldata if data['type']==type]

2
顺便说一句,set(data['type'] for data in alldata)可以在不创建中间列表的情况下完成相同的操作 :-) - mgilson

2
更一般的方法是使用itertools.groupby:
from itertools import groupby

food = [
    {'name': 'apple', 'type': 'fruit'}, 
    {'name': 'pear', 'type': 'fruit'}, 
    {'name': 'parrot', 'type': 'vegetable'}]

for group, items in groupby(sorted(food, key=lambda x: x['type']), lambda x: x['type']):
    print group, list(items) # here is group and items' objects in the group

结果是:

fruit [{'type': 'fruit', 'name': 'apple'}, {'type': 'fruit', 'name': 'pear'}]
vegetable [{'type': 'vegetable', 'name': 'parrot'}]

UPD: 在groupby之前对字典进行排序。感谢@mgilson指出!

创建一个迭代器,该迭代器从可迭代对象中返回连续的键和分组。键是计算每个元素的键值的函数。如果未指定或为None,则键默认为标识函数,并返回元素本身。通常,可迭代对象需要在相同的键函数上已经排序。

https://docs.python.org/2/library/itertools.html#itertools.groupby


就算值得一提的是,除非食物已经按类型预先分类,否则这个做法是行不通的。 - mgilson

1
请使用set结构:
types = set((d['type'] for d in alldata))

我接受了Gabz的答案,因为它还提供了如何构建名称列表的信息。 - kiki
@kik 没问题,由你决定 :-) - BartoszKP

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接