Python 使用列表理解旋转表格CSV数据

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' :

我正在新开发一个工具,它可以帮助我收集以下形式的数据:[{Entity:{Field:Value}},…]

除非另有说明,否则我将这样表示数据:

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')]