【问题标题】:Generators for processing large result sets用于处理大型结果集的生成器
【发布时间】:2014-02-13 11:21:26
【问题描述】:

我正在从一个 sqlite 数据库中检索信息,该数据库返回了大约 2000 万行需要处理的行。然后将此信息转换为我需要使用的列表字典。我正在尝试尽可能使用生成器。

有人可以看看这段代码并提出优化建议吗?我要么收到“Killed”消息,要么需要很长时间才能运行。 SQL 结果集部分工作正常。我在 Python 解释器中测试了生成器代码,它没有任何问题。我猜问题出在 dict 生成上。

为清晰而编辑/更新:

我的 sqlite 数据库的结果集中有 2000 万行。每一行的格式为:

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

我现在需要创建一个以该行的第四个元素“AACAGA”为键的字典。 dict 将保存的值是第三个元素,但它必须保存结果集中所有出现的值。因此,在我们这里的例子中,“AACAGA”将保存一个列表,其中包含来自 sql 结果集中的多个值。这里的问题是在基因组序列中找到串联重复。串联重复是连续重复至少 3 次的基因组读数 (‘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()

【问题讨论】:

  • 您应该尝试在codereview.stackexchange.com 上发布此内容,所以更多的是关于调试。
  • 好吧,我收到一条 Killed 消息,我认为这是内存泄漏。这就是为什么我在这里发布它,看看我是否可以在调试它时获得一些帮助。

标签: python-3.x sqlite generator


【解决方案1】:

正如@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 上线程的链接

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-07
    • 1970-01-01
    • 1970-01-01
    • 2011-01-31
    • 1970-01-01
    • 2020-06-15
    • 2015-07-08
    • 2018-09-20
    相关资源
    最近更新 更多