Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中存储集合数据的最佳方式是什么?_Python_Dictionary_Data Structures_Set - Fatal编程技术网

在Python中存储集合数据的最佳方式是什么?

在Python中存储集合数据的最佳方式是什么?,python,dictionary,data-structures,set,Python,Dictionary,Data Structures,Set,我有以下格式的数据列表: [(id\\\\\\\ 1,描述,id\\类型),(id\\\ 2,描述,id\\类型),…,(id\\\ n,描述,id\\类型)] 数据是从属于同一组的文件加载的。在每个组中可能有多个相同id的文件,每个id来自不同的文件。我不关心重复的文件,所以我认为存储所有这些数据的好方法是将其放入一个集合类型中。但有一个问题 有时,对于同一id,描述可能略有不同,如下所示: IPI00110753 微管蛋白α-1A链 微管蛋白α-1链 α-微管蛋白1 α-微管蛋白M-α-1

我有以下格式的数据列表:

[(id\\\\\\\ 1,描述,id\\类型),(id\\\ 2,描述,id\\类型),…,(id\\\ n,描述,id\\类型)]

数据是从属于同一组的文件加载的。在每个组中可能有多个相同id的文件,每个id来自不同的文件。我不关心重复的文件,所以我认为存储所有这些数据的好方法是将其放入一个集合类型中。但有一个问题

有时,对于同一id,描述可能略有不同,如下所示:

IPI00110753

  • 微管蛋白α-1A链
  • 微管蛋白α-1链
  • α-微管蛋白1
  • α-微管蛋白M-α-1亚型
(请注意,此示例取自。)

我不在乎描述是否不同。我不能扔掉它们,因为我正在使用的蛋白质数据库可能不包含某个标识符的列表。如果发生这种情况,我希望能够向生物学家显示人类可读的描述,以便他们大致知道他们在看什么蛋白质

我目前正在使用字典类型解决这个问题。但是我不太喜欢这个解决方案,因为它占用了很多内存(我有很多这样的ID)。这只是它们的中间列表。在将ID放入数据库之前,需要进行一些额外的处理,因此我希望使我的数据结构更小

我真的有两个问题。首先,我会使用Set类型(比dictionary类型)得到更小的内存占用吗对于这一点,或者我应该使用排序列表,每次插入列表时检查ID是否存在,或者是否有我没有想到的第三种解决方案?第二,如果Set类型是更好的答案,我应该如何键入它以查看元组的第一个元素而不是整个元素

感谢您阅读我的问题,
提姆

更新

根据我收到的一些评论,让我澄清一点。我对数据结构所做的大部分工作都是插入到其中。我只阅读了两次,一次是用附加信息对其进行注释,*还有一次是插入到数据库中。但是,在插入到数据库之前,可能会进行附加注释。不幸的是,我不知道这是否会在这个时候发生

现在,我正在研究将这些数据存储在一个不基于哈希表(即字典)的结构中。我希望新结构在插入时能相当快,但读取它可以是线性的,因为我实际上只做了两次。我正在尝试从哈希表中移开以节省空间。是否有更好的结构,或者哈希表是否尽可能好


*信息是我通过查询uniprot获得的瑞士Prot蛋白质标识符列表。

集合没有键。元素就是键

如果你认为你想要键,你就有了一个映射。根据定义或多或少

顺序列表查找可能会很慢,即使使用二进制搜索也是如此。映射使用哈希,速度很快

你是说像这样的字典吗

{ 'id1': [ ('description1a', 'type1'), ('description1b','type1') ], 
  'id2': [ ('description2', 'type2') ],
...
}
{ 'id1': ( ('description1a', 'description1b' ), 'type1' ),
  'id2': ( ('description2',), 'type2' ),
...
}
这似乎是最小的。ID只表示一次

也许你有这样的东西

{ 'id1': [ ('description1a', 'type1'), ('description1b','type1') ], 
  'id2': [ ('description2', 'type2') ],
...
}
{ 'id1': ( ('description1a', 'description1b' ), 'type1' ),
  'id2': ( ('description2',), 'type2' ),
...
}

除非您使用
struct
模块,否则我不确定您是否可以找到更紧凑的内容。

使用
{id:(描述,id类型)}
字典?或者
{(id,id类型):描述}
字典if(id,id类型)是关键。

Python中的集合是使用哈希表实现的。在早期版本中,它们实际上是使用集合实现的,但这已经改变了。使用集合保存的唯一内容是每个条目的指针大小(指向值的指针)

要仅为hashcode使用元组的一部分,必须对元组进行子类化并重写hashcode方法:

class ProteinTuple(tuple):
     def __new__(cls, m1, m2, m3):
         return tuple.__new__(cls, (m1, m2, m3))

     def __hash__(self):
         return hash(self[0])
请记住,在本例中,您需要为对
\uuuuu hash\uuuu
的额外函数调用付费,否则它将是一个C方法


我会根据Constantin的建议,从元组中取出id,看看这有多大帮助。

我假设您试图通过减少使用的内存来解决的问题是进程的地址空间限制。此外,您会搜索允许快速插入和合理顺序读取的数据结构

使用除字符串(str)以外的更少结构 您要问的问题是如何在一个进程中构造数据以使用更少的内存。一个规范的答案是(只要您仍然需要关联查找),尽可能少地使用python字符串(str,而不是unicode)以外的其他结构。python哈希(字典)相当有效地存储对字符串的引用(它不是b树实现)

然而,我认为这种方法不会走得很远,因为您面临的是巨大的数据集,最终可能会超过您正在使用的机器的进程地址空间和物理内存

替代解决方案 我会提出一个不同的解决方案,不涉及将数据结构更改为更难插入或解释的内容

  • 将您的信息分成多个进程,每个进程都包含方便使用的数据结构
  • 使用套接字实现进程间通信,这样进程就可以完全驻留在其他机器上
  • 尝试划分数据,例如最小化进程间通信(i/o比cpu周期慢得多)
我概述的方法的优点是

  • 为了提高性能,您可以在一台机器上使用两个或更多的内核
  • 您不受一个进程的地址空间,甚至一台机器的物理内存的限制
那里
def unique( sequence ):
    keyPos= 0
    seqIter= iter(sequence)
    curr= seqIter.next()
    for next in seqIter:
        if next[keyPos] == curr[keyPos]:
            # might want to create a sub-list of matches
            continue
        yield curr
        curr= next
    yield curr
for u in unique( merge( source1, source2, source3, ... ) ):
    print u