我有如下代码:
dicts = [
{'one': 'hello',
'two': 'world',
'three': ['a', 'b', 'c', 'd'],
'four': 'foo'
},
{'one': 'pizza',
'two': 'cake',
'three': ['f', 'g', 'h', 'e'],
'four': 'bar'
}
]
letters = ['q', 'w', 'e', 'r','t','y']
dedup_rows = [row for row in dicts if row['three'][3] not in letters]
目标是dedup_rows
应该包含dicts
中的元素,其中three
中存储的列表的第四个元素不包含在列表letters
中。本质上是delete row from dicts if row['three'][3] in letters
。上面代码的输出将是:
dedup_rows: [
{'one': 'hello',
'two': 'world',
'three': ['a', 'b', 'c', 'd'],
'four': 'foo'
}
]
我正在使用的代码正在运行,但实际上dicts
和letters
都包含成千上万个元素,因此执行速度很慢,因为dicts
上的每次迭代都需要完整的迭代超过letters
。
在Python中是否有更优化的方法?
答案 0 :(得分:4)
您的代码dedup_rows = [row for row in dicts if row['three'][3] not in letters]
具有平方复杂度。因为它在dicts
的每个元素上遍历letters
和dicts
。
如果两个列表都包含大量元素。您应该考虑查找时间复杂度约为1的数据结构。对于您的情况,Python Sets很完美。您可以阅读更多有关它的信息。
您需要做的就是将letters = ['q', 'w', 'e', 'r','t','y']
转换为语法为set(letters)
的集合,并以语法x in letters_set
查找。
dicts = [
{'one': 'hello',
'two': 'world',
'three': ['a', 'b', 'c', 'd'],
'four': 'foo'
},
{'one': 'pizza',
'two': 'cake',
'three': ['f', 'g', 'h', 'e'],
'four': 'bar'
}
]
letters = ['q', 'w', 'e', 'r','t','y']
letters_set = set(letters)
dedup_rows = [row for row in dicts if row['three'][3] not in letters_set]
像这样,您可以将算法从n平方的顺序更改为n的顺序。
答案 1 :(得分:1)
如果您实际上要处理成千上万的记录,每个记录中的行各具有成千上万的值,那么也许纯粹的内存python方法并不是最好的方法。
您可以采取一些措施来提高性能:
不过,总的来说,这引出了您从何处获取这些记录的问题?
如果它们存储在任何类型的数据库中,则在源代码处执行查询,以排除不需要的行,并提供一个游标以内存高效的方式遍历您想要的行,听起来像是更好的方法。