示例:
myCmpItem = '511'
myList = ['111','222','333','444','555','123']
(some magic)
mySortedList = ['111', '222', '333', '123', '444', '555']
我可以使用很多for循环来编写代码,但实际上我正在寻找一种更快的方法来实现这一点。有没有算法做那样的事情?快?
所有项目的数字都是问题的答案,我想找到与给定答案集最相似的答案集。所以“123”表示用户回答问题1 =答案1,问题2 =答案2,问题3 =答案3.它们是多项选择题,总共25个问题(=长度为25),总有5个不同可能回答(这些是数字1-5)。
PS:这是我在Stackoverflow上提出的第一个问题所以请与我好心。我已经谷歌搜索了几个小时,但我找不到任何解决方案,所以我在这里问。我希望这很好。英语也不是我的母语。
@larsmans的回答(https://stackoverflow.com/a/10790714/511484)非常清楚地解释了如何以合理的速度解决这个问题。您甚至可以通过提前计算每个数字之间的距离来加速算法,请参阅@ gnibbler的帖子(https://stackoverflow.com/a/10791838/511484)所有其他答案也很好而且正确,但我发现@larsmans有最好的解释。再次感谢大家的帮助!
答案 0 :(得分:7)
首先,从myCmpItem
创建一个整数列表,以使减法成为可能。
myCmpItem = map(int, myCmpItem)
然后,定义一个计算项目与myCmpItem
之间距离的函数。我们还需要将项目映射到整数列表。其余的只是L1 distance的香草公式(你正在计算的“差异”的数学名称)。
def dist(item):
item = map(int, item)
return sum(abs(item[i] - myCmpItem[i]) for i in xrange(len(item)))
然后,将此函数用作key
函数进行排序。
sorted(myList, key=dist)
(PS:你确定L1距离对这个应用程序有意义吗?使用它表示假设答案1更接近答案2而不是答案3等等。如果不是这样,{{3可能更合适。)
答案 1 :(得分:5)
使用lambda
和列表理解:
sorted(myList, key=lambda item: sum([abs(int(x) - int(y)) for x, y in zip(item, myCmpItem)])
答案 2 :(得分:4)
def cmpWith(num):
def compare(item):
""" calculate the difference between num and item """
return sum(
abs(int(n) - int(x)) # cast to int to make the substraction possible
for x,n in zip(item, num) # zip makes pairs from both lists
)
return compare
lst = ['111','222','333','444','555','123']
print sorted(lst, key=cmpWith('511'))
答案 3 :(得分:2)
这个怎么样?
myCmpItem = '511'
myList = ['111','222','333','444','555','123']
def make_key(x):
diff = 0
for a, b in zip(x, myCmpItem):
diff += abs(int(a)-int(b))
return diff
mySortedList = sorted(myList, key=make_key)
print mySortedList
答案 4 :(得分:2)
预先计算距离表可能比将每个数字转换为int
myCmpItem = '511'
myList = ['111','222','333','444','555','123']
# only need to compute this dict once
dists = {(i,j):abs(int(i)-int(j)) for i in '12345' for j in '12345'}
print sorted(myList, key=lambda j: sum(dists[i] for i in zip(j, myCmpItem)))
在我的电脑上,这比larsmans对100000 x 25字符串的回答快2.9倍