Python 使用列表理解旋转表格CSV数据
我正在新开发一个工具,它可以帮助我收集以下形式的数据:[{Entity:{Field:Value}},…] 除非另有说明,否则我将这样表示数据:Python 使用列表理解旋转表格CSV数据,python,csv,dictionary,list-comprehension,Python,Csv,Dictionary,List Comprehension,我正在新开发一个工具,它可以帮助我收集以下形式的数据:[{Entity:{Field:Value}},…] 除非另有说明,否则我将这样表示数据: alldata = [ {'ShinyCorp, Inc.' : [ {'state' : 'CA'}, {'phone' : '123-456-7890'} ] }, {'MultiBiz, LLC' : [ {'state' :
alldata = [
{'ShinyCorp, Inc.' :
[
{'state' : 'CA'},
{'phone' : '123-456-7890'}
]
},
{'MultiBiz, LLC' :
[
{'state' : 'NY'},
{'ceo' : 'Glenn Suggzass'}
]
},
{'Marx Capital Group' :
[
{'state' : 'DE'},
{'fax' : '321-654-0987'}
]
}
]
我想以两种形式呈现数据:
1) 第一列为实体名称列表,每行的列显示该行第一列中所列实体的字段值
2) 第一列为字段名称列表,每行的列显示该列的第一行中所列实体的字段值(也称为标题)
就像这样
(一)
(二)
所以
给定alldata的格式(EntityName或Entented dicts的列表),DictWriter和writerows的列表理解是什么
编辑:这只是一个玩具示例,目的是获得一些好的列表理解建议。非常老的问题,你仍然在身边的机会非常少,但这个问题很有趣 更简单的数据结构 首先,我认为您的数据结构不是最好的。假设您得到这样的元组(来自csv文件): 您必须列出实体和字段及其关系。如果您不关心订单:
>>> data_by_entity = {}
>>> fields = set()
>>> for entity,k,v in csv:
... fields.add(k)
... data_by_entity.setdefault(entity, {})[k] = v
...
>>> data_by_entity
{'ShinyCorp, Inc.': {'state': 'CA', 'phone': '123-456-7890'}, 'MultiBiz, LLC': {'state': 'NY', 'ceo': 'Glenn Suggzass'}, 'Marx Capital Group': {'state': 'DE', 'fax': '321-654-0987'}}
>>> sorted(fields)
['ceo', 'fax', 'phone', 'state']
>>> sorted(data_by_entity.keys())
['Marx Capital Group', 'MultiBiz, LLC', 'ShinyCorp, Inc.']
>>> data_by_entity = {}
>>> fseen = set()
>>> fields = []
>>> eseen = set()
>>> entities = []
>>> for entity,k,v in csv:
... if entity not in eseen:
... entities.append(entity)
... data_by_entity[entity] = {}
... eseen.add(entity)
... if k not in fseen:
... fields.append(k)
... fseen.add(k)
... data_by_entity[entity][k]=v
...
>>> data_by_entity
{'ShinyCorp, Inc.': {'state': 'CA', 'phone': '123-456-7890'}, 'MultiBiz, LLC': {'state': 'NY', 'ceo': 'Glenn Suggzass'}, 'Marx Capital Group': {'state': 'DE', 'fax': '321-654-0987'}}
>>> fields
['state', 'phone', 'ceo', 'fax']
>>> entities
['ShinyCorp, Inc.', 'MultiBiz, LLC', 'Marx Capital Group']
如果您关心订单:
>>> data_by_entity = {}
>>> fields = set()
>>> for entity,k,v in csv:
... fields.add(k)
... data_by_entity.setdefault(entity, {})[k] = v
...
>>> data_by_entity
{'ShinyCorp, Inc.': {'state': 'CA', 'phone': '123-456-7890'}, 'MultiBiz, LLC': {'state': 'NY', 'ceo': 'Glenn Suggzass'}, 'Marx Capital Group': {'state': 'DE', 'fax': '321-654-0987'}}
>>> sorted(fields)
['ceo', 'fax', 'phone', 'state']
>>> sorted(data_by_entity.keys())
['Marx Capital Group', 'MultiBiz, LLC', 'ShinyCorp, Inc.']
>>> data_by_entity = {}
>>> fseen = set()
>>> fields = []
>>> eseen = set()
>>> entities = []
>>> for entity,k,v in csv:
... if entity not in eseen:
... entities.append(entity)
... data_by_entity[entity] = {}
... eseen.add(entity)
... if k not in fseen:
... fields.append(k)
... fseen.add(k)
... data_by_entity[entity][k]=v
...
>>> data_by_entity
{'ShinyCorp, Inc.': {'state': 'CA', 'phone': '123-456-7890'}, 'MultiBiz, LLC': {'state': 'NY', 'ceo': 'Glenn Suggzass'}, 'Marx Capital Group': {'state': 'DE', 'fax': '321-654-0987'}}
>>> fields
['state', 'phone', 'ceo', 'fax']
>>> entities
['ShinyCorp, Inc.', 'MultiBiz, LLC', 'Marx Capital Group']
seen
技巧保留列表中的一组元素。如果(且仅当)元素不在列表中,即。。。不在设定范围内(O(1)与0(n)速度)
这个数据结构可能很容易更新:给循环体一个新的元组
从数据结构到更简单的数据结构
说明:
:这是外部指令用于所有数据中的数据
:实体和内部目录列表对于e,数据项中的值()
:这将合并列表{k:v表示k的值中的值,v表示值中的值。items()}
值中的内部目录
合并列表
功能可能更容易理解:
>>> def merge_list_of_dicts(L): return {k: v for d in L for k,v in d.items()}
>>> data_by_entity = {e:merge_list_of_dicts(values) for e, values in merge_list_of_dicts(alldata).items()}
>>> data_by_entity
{'ShinyCorp, Inc.': {'state': 'CA', 'phone': '123-456-7890'}, 'MultiBiz, LLC': {'state': 'NY', 'ceo': 'Glenn Suggzass'}, 'Marx Capital Group': {'state': 'DE', 'fax': '321-654-0987'}}
从结构中获取字段很容易:
>>> fields = set(k for data in data_by_entity.values() for k,v in data.items())
>>> sorted(fields)
['ceo', 'fax', 'phone', 'state']
输出
现在,问题的答案
中一
说明:
是第一行李>[“EntityName”]+字段]
迭代字段并获取值。它前面是[k]+[v.get(f,”)表示字段中的f]
,字段的名称李>k
对每个实体重复上述列表[[k]+[…]对于数据中的k,v按实体。items()]
是第一行李>[“FieldName”]+实体]
迭代实体并获取给定[k]+[data\u by_entity[e].get(k,”)for e in entities]
的值。它前面是k
,字段的名称李>k
为每个字段重复上述列表[[k]+[…]用于字段中的k]
>>> L = [["EntityName"]+list(fields)]+[[k]+[v.get(f, "") for f in fields] for k, v in data_by_entity.items()]
>>> list(zip(*L))
[('EntityName', 'ShinyCorp, Inc.', 'MultiBiz, LLC', 'Marx Capital Group'), ('ceo', '', 'Glenn Suggzass', ''), ('fax', '', '', '321-654-0987'), ('phone', '123-456-7890', '', ''), ('state', 'CA', 'NY', 'DE')]
说明:
list(zip(*L)
是转换列表的惯用方法。如果L=[L1,…,Ln]
,zip(*L)
将列表解压为zip(L1,…,Ln)
。然后zip
创建一个包含每个列表第一个元素的元组,另一个包含每个列表第二个元素的元组,…直到它耗尽其中一个列表。为什么[{'state':'CA'},{'phone':'123-456-7890'}
而不是{'state':'CA','phone':'123-456 7890'}
?(类似于一个级别,但我想你可能有两行公司信息。)好问题。该工具旨在逐步整理和组织小的、分布广泛的互联网信息位,形成你所描述的组织良好的结构。这就是为什么数据以如此基本的方式表达(实体:键:值)。
>>> fields = set(k for data in data_by_entity.values() for k,v in data.items())
>>> sorted(fields)
['ceo', 'fax', 'phone', 'state']
>>> fields = sorted(fields) # ensure the test is reproducible
>>> [["EntityName"]+fields]+[[k]+[v.get(f, "") for f in fields] for k, v in data_by_entity.items()]
[['EntityName', 'ceo', 'fax', 'phone', 'state'], ['ShinyCorp, Inc.', '', '', '123-456-7890', 'CA'], ['MultiBiz, LLC', 'Glenn Suggzass', '', '', 'NY'], ['Marx Capital Group', '', '321-654-0987', '', 'DE']]
>>> [["FieldName"]+entities]+[[k]+[data_by_entity[e].get(k, "") for e in entities] for k in fields]
[['FieldName', 'ShinyCorp, Inc.', 'MultiBiz, LLC', 'Marx Capital Group'], ['ceo', '', 'Glenn Suggzass', ''], ['fax', '', '', '321-654-0987'], ['phone', '123-456-7890', '', ''], ['state', 'CA', 'NY', 'DE']]
>>> L = [["EntityName"]+list(fields)]+[[k]+[v.get(f, "") for f in fields] for k, v in data_by_entity.items()]
>>> list(zip(*L))
[('EntityName', 'ShinyCorp, Inc.', 'MultiBiz, LLC', 'Marx Capital Group'), ('ceo', '', 'Glenn Suggzass', ''), ('fax', '', '', '321-654-0987'), ('phone', '123-456-7890', '', ''), ('state', 'CA', 'NY', 'DE')]