我有一个CSV文件,我已经过滤到一个列表和分组。示例:
52713
['52713', '', 'Vmax', '', 'Start Value', '', '\n']
['52713', '', 'Vmax', '', 'ECNumber', '1.14.12.17', '\n']
['52713', 'O2', 'Km', 'M', 'Start Value', '3.5E-5', '\n']
['52713', 'O2', 'Km', 'M', 'ECNumber', '1.14.12.17', '\n']
52714
['52714', '', 'Vmax', '', 'Start Value', '', '\n']
['52714', '', 'Vmax', '', 'ECNumber', '1.14.12.17', '\n']
['52714', 'O2', 'Km', 'M', 'Start Value', '1.3E-5', '\n']
['52714', 'O2', 'Km', 'M', 'ECNumber', '1.14.12.17', '\n']由此,我创建了一个嵌套字典,其结构如下:
dict = ID number:{Km:n, Kcat:n, ECNumber:n}...for列表中的每个ID。
我使用以下代码创建此字典
dict = {}
for key, items in groupby(FilteredTable1[1:], itemgetter(0)):
#print key
for subitem in items:
#print subitem
dict[subitem[EntryID]] = {}
dict[subitem[EntryID]]['EC'] = []
dict[subitem[EntryID]]['Km'] = []
dict[subitem[EntryID]]['Kcat'] = []
if 'ECNumber' in subitem:
dict[subitem[EntryID]]['EC'] = subitem[value]
if 'Km' in subitem and 'Start Value' in subitem:
dict[subitem[EntryID]]['Km'] = subitem[value]
#print subitem这适用于ECNumber值,但不适用于Km值。它可以打印这条线,显示它将Km值标识为存在,但不把它放在字典中。
示例输出:
{'Km': [], 'EC': '1.14.12.17', 'Kcat': []}有什么想法吗?
本
发布于 2015-03-13 17:12:36
问题是您的内部for循环一直在重新初始化dict[subitem[EntryID]],即使它可能已经存在。通过显式检查是否已经存在,可以解决以下问题:
dict = {}
for key, items in groupby(FilteredTable1[1:], itemgetter(0)):
#print key
for subitem in items:
#print ' ', subitem
if subitem[EntryID] not in dict:
dict[subitem[EntryID]] = {}
dict[subitem[EntryID]]['EC'] = []
dict[subitem[EntryID]]['Km'] = []
dict[subitem[EntryID]]['Kcat'] = []
if 'ECNumber' in subitem:
dict[subitem[EntryID]]['EC'] = subitem[value]
if 'Km' in subitem and 'Start Value' in subitem:
dict[subitem[EntryID]]['Km'] = subitem[value]
#print subitem但是,通过使用下面这样的方法可以提高代码的效率,从而避免了重新计算值和双字典查找。它也不对变量名使用内置类型的名称,这违背了https://www.python.org/dev/peps/pep-0008/中给出的指导方针。它还建议只对类名使用CamelCase,而不是对FilteredTable1这样的变量名称使用--但我没有改变它。
adict = {}
for key, items in groupby(FilteredTable1[1:], itemgetter(0)):
#print key
for subitem in items:
#print ' ', subitem
entry_id = subitem[EntryID]
if entry_id not in adict:
adict[entry_id] = {'EC': [], 'Km': [], 'Kcat': []}
entry = adict[entry_id]
if 'ECNumber' in subitem:
entry['EC'] = subitem[value]
if 'Km' in subitem and 'Start Value' in subitem:
entry['Km'] = subitem[value]
#print subitem实际上,由于您正在构建字典,所以不清楚使用groupby是否有任何好处。
发布于 2015-03-16 18:34:31
我张贴这篇文章是为了跟进,并在我的previous answer上扩展。
首先,您可以进一步简化代码,方法是不需要检查先前存在的条目,只需将字典创建为collections.defaultdict dict子类,而不是普通的子类:
from collections import defaultdict
adict = defaultdict(lambda: {'EC': [], 'Km': [], 'Kcat': []})
for key, items in groupby(FilteredTable1[1:], itemgetter(0)):
for subitem in items:
entry = adict[subitem[EntryID]]
if 'ECNumber' in subitem:
entry['EC'] = subitem[value]
if 'Km' in subitem and 'Start Value' in subitem:
entry['Km'] = subitem[value]第二,正如我在另一个答案中提到的那样,我认为使用itertools.groupby()来完成这个任务不会获得任何好处--除了使过程变得比需要的更复杂之外。这是因为基本上你要做的是制作一个字典字典,它的条目都可以随机访问,所以在这样做之前麻烦地将它们分组是没有好处的。下面的代码证明了这一点(结合使用上面所示的defaultdict ):
adict = defaultdict(lambda: {'EC': [], 'Km': [], 'Kcat': []})
for subitem in FilteredTable1[1:]:
entry = adict[subitem[EntryID]]
if 'ECNumber' in subitem:
entry['EC'] = subitem[value]
if 'Km' in subitem and 'Start Value' in subitem:
entry['Km'] = subitem[value]https://stackoverflow.com/questions/29035205
复制相似问题