2014-02-13 40 views
0

我正在从sqlite数据库中检索信息,该信息让我回到需要处理的2000万行左右。然后将这些信息转换成我需要使用的列表字典。我尽可能使用发生器。用于处理大型结果集的生成器

有人可以看看这段代码,并建议优化吗?我要么收到“Killed”消息,要么运行很长时间。 SQL结果集部分工作正常。我在Python解释器中测试了生成器代码,并没有任何问题。我猜测问题是与字典一代。为清楚起见

编辑/ UPDATE:

我有我的结果从我的SQLite数据库集20万行。每一行的形式为:

(2786972, 486255.0, 4125992.0, 'AACAGA', '2005’) 

我现在需要创建一个键与该行的第四个元素“AACAGA”的字典。字典将保存的值是第三个元素,但它必须保存结果集中所有事件的值。因此,在我们的例子中,'AACAGA'将包含一个包含来自sql结果集的多个值的列表。这里的问题是找到基因组序列中的串联重复序列。串联重复是连续重复至少三次的基因组阅读('AACAGA')。对于我来计算这个,我需要第三个索引中的所有值作为基因组读取关键字列表,在我们的例子中是'AACAGA'。一旦我有了列表,我可以减去列表中的连续值,以查看是否有三次连续匹配的读取长度。这是我的目标是用字典和列表作为价值来完成。

#!/usr/bin/python3.3 
import sqlite3 as sql 

sequence_dict = {} 
tandem_repeat = {} 

def dict_generator(large_dict): 
    dkeys = large_dict.keys() 
    for k in dkeys: 
     yield(k, large_dict[k]) 

def create_result_generator(): 
    conn = sql.connect('sequences_mt_test.sqlite', timeout=20) 
    c = conn.cursor() 
    try: 
     conn.row_factory = sql.Row 
     sql_string = "select * from sequence_info where kmer_length > 2" 
     c.execute(sql_string) 
    except sql.Error as error: 
     print("Error retrieving information from the database : ", error.args[0]) 
    result_set = c.fetchall() 
    if result_set: 
     conn.close() 
     return(row for row in result_set) 

def find_longest_tandem_repeat(): 
    sortList = [] 
    for entry in create_result_generator(): 
     sequence_dict.setdefault(entry[3], []).append(entry[2]) 

    for key,value in dict_generator(sequence_dict): 
     sortList = sorted(value) 
     for i in range (0, (len(sortList)-1)): 
      if((sortList[i+1]-sortList[i]) == (sortList[i+2]-sortList[i+1]) 
       == (sortList[i+3]-sortList[i+2]) == (len(key))): 
        tandem_repeat[key] = True 
        break 

    print(max(k for k, v in tandem_repeat.items() if v)) 

if __name__ == "__main__": 
    find_longest_tandem_repeat() 
+0

您应该尝试在http://codereview.stackexchange.com/上发布该内容。SO更多地是关于调试。 – hivert

+0

好吧,我收到了一条我认为是内存泄漏的Killed消息。这就是为什么我在这里发布它,看看我是否可以得到一些调试帮助。 – adwaraki

回答

0

作为@hivert建议,我在codereview上获得了一些帮助。谢谢。这在SQL中更好解决,而不仅仅是代码。我是SQL新手,因此无法编写复杂的查询。有人帮我解决了这个问题。

SELECT * 
    FROM sequence_info AS middle 
     JOIN sequence_info AS preceding 
      ON preceding.sequence_info = middle.sequence_info 
      AND preceding.sequence_offset = middle.sequence_offset - 
       length(middle.sequence_info) 
     JOIN sequence_info AS following 
      ON following.sequence_info = middle.sequence_info 
      AND following.sequence_offset = middle.sequence_offset + 
       length(middle.sequence_info) 
    WHERE middle.kmer_length > 2 
    ORDER BY length(middle.sequence_info) DESC, middle.sequence_info, 
     middle.sequence_offset; 

希望这可以帮助一个人有大约相同的想法。 Here是codereview.stackexchange.com上的主题的链接