我正在尝试执行以下python代码,该代码将按字母顺序返回" ABCDEGGHIJK"的第一个排列。它需要一个非常简单的排序算法,如Project Euler问题336中定义的最大迭代次数排序。
这是代码(对于错误的变量名称道歉):
from itertools import permutations
def first_out_letter(st):
"""
returns the first letter alphabetically in st which is not in sorted order
alphabetically, string must be all in captials.
"""
def first(string):
"""
returns the first alphabetical letter in a string, only capitals allowed
"""
alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
for i in alpha:
if i in string:
return i
return None
sor = ''.join(sorted(st))
for i in range(len(st)):
if st[i] != sor[i]:
return first(st[i:])
return None
def get_arrangement_size(arrang,dictionary):
"""
returns the number of shifts needed to arrange a string in lexographic order
using a dumb method of first getting the first digit correct, then the second
and so on...
the argument dictionary stores precomputed results and is modified during execution.
"""
if arrang in dictionary.keys():
return dictionary[arrang]
sor = ''.join(sorted(arrang))
if arrang == sor:
dictionary[arrang] = 0
return 0
else:
bing = first_out_letter(arrang)
num_arr = 0
pos_bing = 0
for i in range(len(arrang)):
if arrang[i] == sor[i]:
num_arr += 1
else:
break
for i in range(len(arrang)):
if arrang[i] != bing:
pos_bing += 1
else:
break
if bing == arrang[-1]:
low = get_arrangement_size(arrang[:num_arr]+arrang[num_arr:][::-1],dictionary)
else:
low = get_arrangement_size(arrang[:pos_bing]+arrang[pos_bing:][::-1],dictionary)
dictionary[arrang] = low+1
return low+1
solutions = {}
letters = ["A","B","C","D","E","F","G","H","I","J","K"]
piv = permutations(letters)
for item in piv:
get_arrangement_size(''.join(item),solutions) #builds up the solutions dictionary
ma = max(solutions.values())
fir = []
for item in solutions.keys():
if solutions[item] == ma:
fir.append(item)
fir = sorted(fir)
print(fir[0])
代码在我的两台机器上运行正常并给出了正确的答案但我在两台机器上看到的速度差异高达20倍。
我的(理论上)带有i5的更快的计算机正在运行Linux Mint和python 2.7.6并且还有更多的内存但是当我运行这段代码时,我发现它的运行速度比我在较慢的计算机上运行要快得多Windows和python 3.5.1。当我在我的任何一台机器上运行此代码并且它们都使用相同的IDE(Spyder)时,我没有同时运行其他任何东西,所以我不知道为什么会出现这种速度差异?
非常感谢任何帮助或理由来解释这一点。
编辑:正如Chriss'建议我尝试在较慢的计算机上在python 2.7上运行此代码,它也比在同一台计算机上运行3.5上的代码要慢得多。所以这个差异是由python版本引起的,但究竟是什么导致了我不知道并且仍然想知道的差异。
答案 0 :(得分:4)
这是由Python 2和3之间dict.keys()
的差异引起的。在Python 2中dict.keys()
将创建密钥副本作为列表并返回它。在Python 3中,dict.keys()
将返回dictionary view
,而不是set
对象。检查是否可以从list
找到元素要比检查set
中的元素是否慢慢解释差异要慢得多。
如果进行以下更改,代码将在Python 2& 3:
if arrang in dictionary: # Instead of if arrang in dictionary.keys()
return dictionary[arrang]