【问题标题】:Can I change this three loops into one or do something else to make this code faster?我可以将这三个循环变为一个循环或做其他事情来使这段代码更快吗?
【发布时间】:2025-12-31 03:10:07
【问题描述】:

我需要有关 python 代码的帮助,因为这对我来说太慢了。我想让这个更快,但我不知道怎么做。我认为循环必须更少。我什至计算过 (length - 2) ^ 3 = length^3 + 12 * length - 6 * (length^2) - 8 但我不知道如何使用它。请帮忙!代码:

word = "a word"
letter_1 = ""
letter_2 = ""
letters = list(word)
length = len(letters)
string = ""
number = 0
number2 = 0
words = []

for i in range(length - 2):
    letter_1 = letters[i]

    for j in range(i + 1,length - 1):
        
        if letters[j] != letter_1:
            letter_2 = letters[j]
            
            for k in range(j + 1, length):
                
                if letters[k] != letter_2:
                    string = letter_1 + letter_2 + letters[k]
                    number += 1
                    
                    if not string in words:
                        words.append(string)
                        number2 += 1

【问题讨论】:

  • 欢迎来到 *。帮助我们帮助您:请解释您的算法应该做什么,这样我们就不必对其进行逆向工程,并且可以更轻松地为您提供帮助。只需编辑您的答案。
  • 欢迎来到 Stack Overflow!不要破坏你的帖子。通过在本网站上发布,您已不可撤销地授予 Stack Exchange 网络以CC BY-SA 4.0 license 分发该内容的权利,只要它认为合适即可。有关删除的替代方法,请参阅:I've thought better of my question; can I delete it?

标签: python performance loops velocity


【解决方案1】:

在包itertools中有一个特殊的函数叫做combinations

>>> from itertools import combinations
>>> list(combinations("a word", 3))
[('a', ' ', 'w'), ('a', ' ', 'o'), ('a', ' ', 'r'), ('a', ' ', 'd'), ('a', 'w', 'o'), ('a', 'w', 'r'), ('a', 'w', 'd'), ('a', 'o', 'r'), ('a', 'o', 'd'), ('a', 'r', 'd'), (' ', 'w', 'o'), (' ', 'w', 'r'), (' ', 'w', 'd'), (' ', 'o', 'r'), (' ', 'o', 'd'), (' ', 'r', 'd'), ('w', 'o', 'r'), ('w', 'o', 'd'), ('w', 'r', 'd'), ('o', 'r', 'd')]

【讨论】:

    【解决方案2】:

    我假设您的代码尝试在名为 word 的字符串中获取所有唯一的三元组。如果我的假设不正确,请忽略我的回答并纠正我。

    如果是这样的话,我建议进行以下改进:

    1. 既然你想要独特的结果,一个列表并不理想,使用一个集合;将words = [] 替换为words = set()words.append(string) 替换为words.add(string)

    2. 由于您在第一个位置找到一个字母时从左到右检查唯一的三元组,当您在第一个位置再次遇到它时,您可能会忽略它,因为您确定您已经遍历了所有在第一个位置与此类字母组合;所以你可以创建额外的集合来验证一个字母是否已经被选中:

      例如对于word = 'aabc',您首先将a 放在第一位,然后对照abc 进行检查;当您再次获得a 时,您无需再次检查以下字母

      第二个位置也是如此,因此您可以为已检查的前缀创建一个变量seen_prefixes = set();然后:

      word = "a word"
      letter_1 = ""
      letter_2 = ""
      letters = list(word)
      length = len(letters)
      string = ""
      number = 0
      number2 = 0
      words = set()
      seen_prefixes = set()
      
      for i in range(length - 2):
          letter_1 = letters[i]
          # check for prefix and add if is a new prefix
          if letter_1 in seen_prefixes:
              continue
          seen_prefixes.add(letter_1)
      
          for j in range(i + 1,length - 1):
      
              if letters[j] != letter_1:
                  letter_2 = letters[j]
                  # check for prefix and add if is a new prefix
                  if letter_1 + letter_2 in seen_prefixes:
                      continue
                  seen_prefixes.add(letter_1 + letter_2)
      
                  for k in range(j + 1, length):
      
                      if letters[k] != letter_2:
                          string = letter_1 + letter_2 + letters[k]
                          number += 1
      
                          if not string in words:
                              words.add(string)
                              number2 += 1
      

      请记住,如果变量 number 的值(我假设是检查的三元组的数量)很重要,那么这种改进将不适合您

    我认为这些改进可以提高速度,因为迭代次数会大大减少,尤其是当您的 word 变量变大时。

    与性能无关,但我还建议让您的代码更具可读性,也许封装一些循环并重命名变量,例如numberchecked_trigramsnumber2unique_trigrams_found

    【讨论】:

    • 所以我认为你的回答很有帮助,因为我需要让我的程序更快。所以谢谢。