示例:
L = [12,14,22,41,21,23]
我希望结果是:
R == [12,14,22,23]
数字的数字必须按递增的顺序排列,以下是我的解决方案,它们都有效,但它们都太慢了。
最快的排序方法是什么?
解决方案一:
R = filter(lambda j: int(''.join(sorted(str(j))))==j , L)
解决方案二:
for j in L:
if int(''.join(sorted(str(j))))==j:
R.append(j)
问题2 - 此外,我希望将这些相应数字的总和等于5。
以下是我的解决方案,它们确实有效,但速度太慢。
那么最快的方法是什么。
newR_should_be == [14,23]
之一:
newR = filter(lambda i: sum([int(x) for x in str(i)])==5 ,R)
2:
for i in R:
if sum([int(x) for x in str(i)])==5:
newR.append(i)
任何帮助都将不胜感激。
答案 0 :(得分:4)
OlivierMelançon解决方案非常优雅。但是,如果您愿意编写有点丑陋的代码,可以通过避免字符串转换并立即执行两个测试来使其运行得更快。我将你的解决方案ast1,OlivierMelançon实现为t2,将我的解决方案实现为t3。
def FastFilter(n):
x = n % 10
s = x
n //= 10
while n:
y = n % 10
s += y
if (x < y):
return False
x = y;
n //= 10
return s==5
def sort_by_digits(l):
return sorted(set(int(''.join(sorted(str(x)))) for x in l))
def filter_by_sum(l, total=5):
return [x for x in map(str, l) if sum(map(int, x)) == total]
def t1(L):
R = filter(lambda j: int(''.join(sorted(str(j))))==j , L)
newR = filter(lambda i: sum([int(x) for x in str(i)])==5 ,R)
return sorted(newR)
def t2(l):
return sort_by_digits(filter_by_sum(l))
def t3(l):
return sorted(filter(FastFilter, l))
l = [12, 14, 22, 41, 21, 23]
%timeit t1(l)
%timeit t2(l)
%timeit t3(l)
给出
11.2 µs ± 24.2 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
8.88 µs ± 24.4 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
2.71 µs ± 12.8 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
答案 1 :(得分:0)
如果您正在尝试使用功能方法,即filter
,您可以尝试:
L = [12,14,22,41,21,23]
while not all(L[i] <= L[i+1] for i in range(len(L)-1)):
L = map(lambda x:x[-1], filter(lambda x:L[x[0]+1] >= x[-1] if x[0]+1 < len(L) else True, zip(range(len(L)), L)))
print(L)
输出:
[12, 14, 21, 23]
答案 2 :(得分:0)
依靠Python内置通常是最有效的方法。它还允许只用几行代码做很多事情。
l = [12, 14, 22, 41, 21, 23]
def sort_by_digits(l):
return sorted(set(int(''.join(sorted(str(x)))) for x in l))
sort_by_digits(l) # [12, 14, 21, 23]
至于总和,你可以做类似的事情。
def filter_by_sum(l, total=5):
return [x for x in map(str, l) if sum(map(int, x)) == total]
sort_by_digits(filter_by_sum(l)) # [14, 23]
答案 3 :(得分:0)
这是我不喜欢Python的一个原因:你提出的简单解决方案,在大多数语言中运行良好,可能与Python中的糖蜜一样慢。太多的高级别操作。
但我们可以通过如下使用Numpy来解决这个问题:
#!/usr/bin/env python3
import numpy as np
COUNT = 1000
MAXNUM = 100000
MAXDIGITS = 6
prevremain = 99*np.ones(COUNT) #The previous digit we removed from the RHS
origdata = np.random.randint(0,MAXNUM,size=COUNT) #Original data
quot = origdata.copy() #What's left when we remove a digit from the RHS
good = np.ones(COUNT) #Whether the number's digits are monotonically decreasing from right to left
for i in range(1,MAXDIGITS): #Pull digits off of the numbers one at a time
quot, remain = np.divmod(quot,10) #quot is the rest of the number, remain is the right-most digit
#Check to see if this digit was smaller, or equal to, than the last one we
#removed. NOTE: If you have numbers with an unequal number of digits, you'll
#need to think carefully about whether `<=` might work better for you.
good = np.logical_and(good, (remain < prevremain))
prevremain = remain
#These are the numbers you want
print(origdata[good])
Numpy将更多的计算工作卸载到快速工作的低级库中。在这种情况下,它可以使用矢量化数学运算来快速对整个输入执行数字检查。然后,您可以将它们用作过滤器。