我目前正在努力寻找一种有效的方法来将附加到列表的字符串元素的一部分与另一个字符串元素进行比较。当前的代码计算非常长(1小时,第一个列表中有4,8百万个元素,第二个列表中有5000个元素)。
我需要做的是:如果第一个字符串元素的8个第一个字符等于完整的第二个元素,则使用完整的第一个元素更新第三个列表。一旦找到,我们测试第一个列表中的另一个元素。
以下是代码:
for first_element in first_List :
for second_element in second_List:
if first_element[:8] == second_element :
third_List.append(first_element)
break
我知道这些循环不是处理非常大的列表的最佳方式。 if
测试的数量非常多。
我想知道是否有一种有效的方法来做到这一点。
我认为与集合的交集不会起作用,因为我将元素的一部分与完整元素进行比较,我需要复制第三个列表中的完整第一个元素。
您有什么建议或想法吗?
答案 0 :(得分:4)
这有效:
second_set = set(second_list)
third_list = [value for value in first_list if value[:8] in second_set]
示例:
>>> first_list = ['abcdfghij', 'xyzxyzxyz', 'fjgjgggjhhh']
>>> second_list = ['abcdfghi', 'xyzxyzxy', 'xxx']
>>> second_set = set(second_list)
>>> third_list = [value for value in first_list if value[:8] in second_set]
>>> third_list
['abcdfghij', 'xyzxyzxyz']
这应该更有效率。
将列表second_list
转换为集合O(n)
。
first_list
上有一个循环O(n)
。 set
中的查询,即in second_set
为O(1)
。
答案 1 :(得分:1)
考虑在python中使用哈希集,或仅使用Set。 关于哈希集的好处是它可以检查一个元素是否在集合中非常快(O(1)),在你的情况下,通过迭代的O(n)解决方案将运行时间提高了5000倍每次都在列表中。
答案 2 :(得分:1)
创建一个新列表,其元素取自first_List
,前提是second_List
中存在其初始部分(8个字符):
third_List = [x for x in first_List if x[:8] in second_List]
应使用second_Set
代替second_List
来优化此方法:
second_Set = set(second_List)