在Python中使用列表而不是dicts进行优化

在Python中使用列表而不是dicts进行优化,python,optimization,python-3.2,Python,Optimization,Python 3.2,我有一些Python代码,比实际应该的速度慢得多 #Generate planets for t in range(stars*3): #There are 3 planets for every star, but not every star will have 3 planets theplanet=Planet() if random.randint(0,100) <= 25: #25% of planets have life theplanet

我有一些Python代码,比实际应该的速度慢得多

#Generate planets
for t in range(stars*3): #There are 3 planets for every star, but not every star will have 3 planets
    theplanet=Planet()

    if random.randint(0,100) <= 25: #25% of planets have life
        theplanet.tl=random.randint(1,9)    #With a random tech level
    else:
        theplanet.tl=0  #The rest don't

    theplanet.star=stardict[random.choice(list(stardict.keys()))]     #Choose a random star
    theplanet.star.planets+=(theplanet,)    #Append the new planet to the star's list of planets
    theplanet.name=theplanet.star.name+"-"+str(len(theplanet.star.planets)) #Name the planet Starname-X, where X is the length of the star's planets tuple. Since this increases every time a planet is added, it will be 1 for the first planet, 2 for the next, etc...

    if math.floor((t/(stars*3))*100)==(t/(stars*3))*100: print("Generating planets: "+str((t/(stars*3))*100)+"% done.")
生成行星 对于范围内的t(恒星*3):#每颗恒星有3颗行星,但并非每颗恒星都有3颗行星 行星
如果random.randint(0100)您每次都在循环中创建一个列表,但该列表是不变的。将其移出循环

starlist=list(stardict.keys())
...
    theplanet.star=stardict[random.choice(starlist)]     #Choose a random star

问题几乎肯定不在dict查找中。它们基于非常快速的哈希表。

您每次通过循环都会创建一个列表,但该列表是不变的。将其移出循环

starlist=list(stardict.keys())
...
    theplanet.star=stardict[random.choice(starlist)]     #Choose a random star
问题几乎肯定不在dict查找中。它们基于非常快速的哈希表

  • 将列表生成
    列表(stardict.keys())
    移动到循环之外

  • 尝试分析您的代码()

  • 假设您正在运行CPython,请检查您的代码是否可以使用。由于其优化的JIT,这可能导致更好的性能

  • 将列表生成
    列表(stardict.keys())
    移动到循环之外

  • 尝试分析您的代码()

  • 假设您正在运行CPython,请检查您的代码是否可以使用。由于其优化的JIT,这可能导致更好的性能


  • 您只能在中间值中使用键as来选择stardict中的随机项。您可以直接使用字典的值列表:

    #Generate planets
    starlist = stardict.values()
    for t in range(stars*3): #There are 3 planets for every star, but not every star will have 3 planets
        theplanet=Planet()
    
        if random.randint(0,100) <= 25: #25% of planets have life
            theplanet.tl=random.randint(1,9)    #With a random tech level
        else:
            theplanet.tl=0  #The rest don't
    
        theplanet.star=random.choice(starlist)     #Choose a random star
        theplanet.star.planets+=(theplanet,)    #Append the new planet to the star's list of planets
        theplanet.name=theplanet.star.name+"-"+str(len(theplanet.star.planets)) #Name the planet Starname-X, where X is the length of the star's planets tuple. Since this increases every time a planet is added, it will be 1 for the first planet, 2 for the next, etc...
    
        if math.floor((t/(stars*3))*100)==(t/(stars*3))*100: print("Generating planets: "+str((t/(stars*3))*100)+"% done.")
    
    生成行星 starlist=stardict.values() 对于范围内的t(恒星*3):#每颗恒星有3颗行星,但并非每颗恒星都有3颗行星 行星
    如果random.randint(0100)您只使用中间值中的键as来选择stardict中的随机项。您可以直接使用字典的值列表:

    #Generate planets
    starlist = stardict.values()
    for t in range(stars*3): #There are 3 planets for every star, but not every star will have 3 planets
        theplanet=Planet()
    
        if random.randint(0,100) <= 25: #25% of planets have life
            theplanet.tl=random.randint(1,9)    #With a random tech level
        else:
            theplanet.tl=0  #The rest don't
    
        theplanet.star=random.choice(starlist)     #Choose a random star
        theplanet.star.planets+=(theplanet,)    #Append the new planet to the star's list of planets
        theplanet.name=theplanet.star.name+"-"+str(len(theplanet.star.planets)) #Name the planet Starname-X, where X is the length of the star's planets tuple. Since this increases every time a planet is added, it will be 1 for the first planet, 2 for the next, etc...
    
        if math.floor((t/(stars*3))*100)==(t/(stars*3))*100: print("Generating planets: "+str((t/(stars*3))*100)+"% done.")
    
    生成行星 starlist=stardict.values() 对于范围内的t(恒星*3):#每颗恒星有3颗行星,但并非每颗恒星都有3颗行星 行星
    如果random.randint(0100),您对字典查找的理解似乎不正确。DICT是散列表——因此查找(平均)需要O(1)个操作——不需要搜索。您假设错误。dict是基于哈希表的,哈希表几乎是最有效的查找方式。@MarkRansom:虽然OP关于dict查找的信息是错误的,但从技术上讲,将其放入列表中可能会增加更多。(这将消除散列步骤和任何冲突的可能性)。不过,这种改进可能是微不足道的。啊,我原以为这可能是一种哈希查找,但后来我想知道如何处理哈希值之间的所有内存空间……您对字典查找的理解似乎不正确。DICT是散列表——因此查找(平均)需要O(1)个操作——不需要搜索。您假设错误。dict是基于哈希表的,哈希表几乎是最有效的查找方式。@MarkRansom:虽然OP关于dict查找的信息是错误的,但从技术上讲,将其放入列表中可能会增加更多。(这将消除散列步骤和任何冲突的可能性)。不过,这种改进可能是微不足道的。啊,我原以为这可能是一种哈希查找,但后来我想知道如何处理哈希值之间的所有内存空间……而stardict.keys()已经是一个列表,因此您不需要外部列表()@tdelaney不需要(OP使用的是Python 3,其中它是一个)。@tdelaney,即使是这样,强制执行也没有什么坏处,我只是复制了原始代码。@Katrielex-我没有注意到这是python 3。我可能有点落后于时代。我应该抓住这一点——尽管让starlist=list(stardict.values())跳过额外的查找不是更好吗P…和stardict.keys()已经是一个列表,所以您不需要外部列表()@tdelaney不,它不是(OP使用的是Python 3,它是一个)。@tdelaney,即使它是,强制它也没什么害处,我只是复制了原始代码。@KatrieleAlex-我没有注意到这是Python 3。我可能有点落后于时代。我应该抓住这一点——尽管让starlist=list(stardict.values())跳过额外的查找不是更好吗P