【问题标题】:Efficient way to loop on comparing string list element to a string list sub-element循环比较字符串列表元素和字符串列表子元素的有效方法
【发布时间】:2015-12-31 11:25:28
【问题描述】:

我目前正在努力寻找一种有效的方法来将附加到列表的字符串元素的一部分与另一个字符串元素进行比较。当前的代码计算很长(1 小时,第一个列表中有 480 万个元素,第二个列表中有 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 测试的数量真的很大。 我想知道是否有有效的方法来做到这一点。

我认为与集合的交集不起作用,因为我将元素的一部分与完整元素进行比较,并且我需要将完整的第一个元素复制到第三个列表中。

请问您有什么建议或想法吗?

【问题讨论】:

  • 您可以考虑使用 blist 包中的 sortedlist 作为第二个列表,并使用 if first_element[:8] in second_sorted_List 跳过第二个循环。

标签: python string list intersection


【解决方案1】:

这行得通:

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_setO(1)

【讨论】:

  • 在列表 comp 中创建 set 比只检查列表要慢
  • @PadraicCunningham 你是对的。固定的。创建集合一次就足够了。 ;)
【解决方案2】:

考虑使用哈希集,或者在 python 中只使用Set。 哈希集的好处是它可以检查一个元素是否在集合中非常快(O(1)),在你的情况下,运行时间比迭代的 O(n)解决方案提高了 5000 倍每次都列出来。

【讨论】:

    【解决方案3】:

    创建一个新列表,其元素取自 first_List,前提是其初始部分(8 个字符)存在于 second_List 中:

    third_List = [x for x in first_List if x[:8] in second_List]
    

    应该使用second_Set而不是second_List来优化这种方法:

    second_Set = set(second_List)
    

    【讨论】:

      猜你喜欢
      • 2015-01-23
      • 2017-02-02
      • 1970-01-01
      • 2021-10-17
      • 1970-01-01
      • 2019-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多