您可以像这样生成集合:
>>> n=3
>>> s={(min(x,y),max(x,y)) for x in range(1,n+1) for y in range(1,n+1)}
>>> s
set([(1, 2), (1, 3), (3, 3), (2, 3), (2, 2), (1, 1)])
并像这样排序:
>>> sorted(s,key=lambda t: -t[0]*t[1])
[(3, 3), (2, 3), (2, 2), (1, 3), (1, 2), (1, 1)]
但是你根本不需要这样做。只需使用嵌套理解:
>>> [(x,y) for x in range(3,0,-1) for y in range(3,x-1,-1)]
[(3, 3), (2, 3), (2, 2), (1, 3), (1, 2), (1, 1)]
这导致了针对该特殊问题的一条线:
print max(x*y for x in range(1000,100,-1) for y in range(1000,x-1,-1)
if str(x*y)==str(x*y)[::-1])
如果你真的想按照你建议的方式去做,你可以使用bisect
:
def PE4():
import bisect
def ispal(n):
return str(n)==str(n)[::-1]
r=[]
for x in xrange(1000,100,-1):
for y in xrange(1000,x-1,-1):
if ispal(x*y): bisect.insort(r,(x*y,x,y))
return r[-1]
该列表r
以递增顺序结束,因为这是 bisect 支持的唯一顺序。
您还可以使用heapq
:
def PE4_4():
import heapq
def ispal(n): return str(n)==str(n)[::-1]
r=[]
for x in xrange(100,1001):
for y in xrange(x,1001):
if ispal(x*y): heapq.heappush(r,(-x*y,x,y))
return (-r[0][0],r[0][1],r[0][2])
如果我计时这些:
import timeit
def PE4_1():
def ispal(n): return str(n)==str(n)[::-1]
return max((x*y,x,y) for x in xrange(1000,99,-1) for y in xrange(1000,x-1,-1) if ispal(x*y))
def PE4_2():
import bisect
def ispal(n): return str(n)==str(n)[::-1]
r=[]
for x in xrange(1000,99,-1):
for y in xrange(1000,x-1,-1):
if ispal(x*y): bisect.insort(r,(x*y,x,y))
return r[-1]
def PE4_3():
import bisect
def ispal(n): return str(n)==str(n)[::-1]
r=[]
for x in xrange(100,1001):
for y in xrange(x,1001):
if ispal(x*y): bisect.insort(r,(x*y,x,y))
return r[-1]
def PE4_4():
import heapq
def ispal(n): return str(n)==str(n)[::-1]
r=[]
for x in xrange(100,1001):
for y in xrange(x,1001):
if ispal(x*y): heapq.heappush(r,(-x*y,x,y))
return (-r[0][0],r[0][1],r[0][2])
n=25
for f in (PE4_1,PE4_2,PE4_3,PE4_4):
fn=f.__name__
print fn+':'
print '\t',f()
res=str(timeit.timeit('{}()'.format(fn),setup="from __main__ import {}".format(fn), number=n))
print '\t'+res+' seconds\n'
它打印:
PE4_1:
(906609, 913, 993)
10.9998581409 seconds
PE4_2:
(906609, 913, 993)
10.5356709957 seconds
PE4_3:
(906609, 913, 993)
10.9682159424 seconds
PE4_4:
(906609, 913, 993)
11.3141870499 seconds
表明该bisect
方法略快,其次是生成器的最大值。heapq
是最慢的方法(勉强)
长答案,但可能产生您想要的列表顺序的最佳方法是以这种方式排序:
我对 Knooth 的解决方案进行了计时,找到第一个带有约束的数字非常优越:
def PE4_6():
def ispal(n): return str(n)==str(n)[::-1]
def gen(n=1000):
heap=[]
visited=set([n*n])
prod=n*n
heapq.heappush(heap,(-prod,n,n))
while abs(prod)>1:
(prod,x,y)=heapq.heappop(heap)
yield -prod,x,y
p1,p2=(x-1)*y, x*(y-1)
if p1 not in visited:
heapq.heappush(heap, (-p1, x-1,y))
visited.add(p1)
if p2 not in visited:
heapq.heappush(heap, (-p2, x,y-1))
visited.add(p2)
it=iter(gen())
t=next(it)
while not ispal(t[0]):
t=next(it)
return t
但是找到整个列表的速度较慢。