如何使用sqlite3在Python中找到元组中的重复项?

时间:2013-09-12 12:28:13

标签: python python-2.7 sqlite pyqt

我是Python的新手,但我爱上了这门语言!

我有一个巨大的sqlite3数据库,其中包含row 0中文件的路径和MD5中的文件row 3

我需要根据MD5搜索重复文件,并且我希望将这些重复文件组织为dictionaries,如下所示:

{"b23e5d453643f66b68634d0204884cdf":an array of all paths that have the same MD5, like the one that is the key of this dictionary}

我正在使用以下代码搜索数据库并制作tuples

    db = sqlite3.connect('imges.db')
    with db:
        cur = db.cursor()    
        cur.execute("SELECT * FROM IMAGES")
    while True:
        row = cur.fetchone()
        if row == None:
            break
        self.duplesOfMD5 = [[row[3]],[row[0]]]
        print self.duplesOfMD5

这给了我以下输出:

[[u'b23e5d453643f66b68634d0204884cdf'], [u'/Volumes/Backup/images_to_test/File_one_copy.png']]
[[u'b23e5d453643f66b68634d0204884cdf'], [u'/Volumes/Backup/images_to_test/File_one.png']]
[[u'f0b4108172c50f243d9e0132df4703a0'], [u'/Volumes/Backup/images_to_test/File_with_no_duplicate.png']]

我尝试过的每一个可能的解决方案都非常充足且性能非常糟糕。什么是最好的pythonic方式来做到这一点?

谢谢!

3 个答案:

答案 0 :(得分:2)

你可以将cur放在循环中,只检索你实际使用的列,并在循环中使用元组解包,如下所示:

db = sqlite3.connect('imges.db')
with db:
    cur = db.cursor()    
    cur.execute("SELECT row1, row3 FROM IMAGES")

    for row1, row3 in cur:
        print [[row3],[row1]]

另外,为什么不使用DISTINCT

cur.execute("SELECT DISTINCT row1, row3 FROM IMAGES")

答案 1 :(得分:2)

如果我理解正确,你需要这样的东西:

{u'b23e5d453643f66b68634d0204884cdf':
     [u'/Volumes/Backup/images_to_test/File_one_copy.png', u'/Volumes/Backup/images_to_test/File_one.png'],
 u'f0b4108172c50f243d9e0132df4703a0':
     [u'/Volumes/Backup/images_to_test/File_with_no_duplicate.png']
}

这非常适合defaultdict(自Python 2.5起可用)

from collections import defaultdict

grouped_by_md5 = defaultdict(list)
db = sqlite3.connect('imges.db')
with db:
    cur = db.cursor()    
    cur.execute("SELECT row1, row3 FROM IMAGES")

    for row1, row3 in cur:
        grouped_by_md5[row3].append(row1)

答案 2 :(得分:1)

如果要通过MD5进行组合,则需要首先按MD5排序列表。在您的情况下,最好留给sqlite,因此您应该在查询中添加一个订单(请参阅例如https://mariadb.com/kb/en/order-by-clause/)。之后,您应该循环遍历所有行,并沿着以下行执行操作:

if currentMD5 != previousMD5:
  dictionary[currentMD5] = [currentFilePath]
else:
  dictionary[currentMD5].append(currentFilePath]
currentMD5 = previousMD5