3

我已经开始研究一些 Project Euler 问题,并用一个简单的蛮力解决方案解决了第 4个问题:

def mprods(a,b):
 c = range(a,b)
 f = []
 for d in c:
  for e in c:
   f.append(d*e)
 return f

max([z for z in mprods(100,1000) if str(z)==(''.join([str(z)[-i] for i in range(1,len(str(z))+1)]))])

解决后,我试图让它尽可能紧凑,并得出了那个可怕的底线!

不要半途而废,我试图将mprods函数压缩为列表理解。到目前为止,我已经提出了这些尝试:

  • [d*e for d,e in (range(a,b), range(a,b))]
    显然完全走错了路。:-)
  • [d*e for x in [e for e in range(1,5)] for d in range(1,5)]
    这给了我[4, 8, 12, 16, 4, 8, 12, 16, 4, 8, 12, 16, 4, 8, 12, 16],我期望 [1, 2, 3, 4, 2, 4, 6, 8, 3, 6, 9, 12, 4, 8, 12, 16]或类似的地方。

有任何 Pythonistas 可以提供帮助吗?:)

4

3 回答 3

7
c = range(a, b)
print [d * e for d in c for e in c]
于 2010-02-24T20:21:17.410 回答
3
from itertools import product

def palindrome(i):
  return str(i) == str(i)[::-1]

x = xrange(900,1000)

max(a*b for (a,b) in (product(x,x)) if palindrome(a*b))
  • xrange(900,1000)就像range(900,1000)但不是返回一个列表,而是返回一个对象,该对象根据需要生成范围内的数字。对于循环,这比 range() 稍快,并且内存效率更高。

  • product(xrange(900,1000),xrange(900,1000))给出输入迭代的笛卡尔积. 它相当于嵌套的 for 循环。例如,product(A, B)返回与: 相同 ((x,y) for x in A for y in B)。最左边的迭代器位于最外层的 for 循环中,因此输出元组以类似于里程表的方式循环(每次迭代中最右边的元素都会发生变化)。

    product('ab', range(3))--> ('a',0) ('a',1) ('a',2) ('b',0) ('b',1) ('b',2) product((0,1), (0,1), (0,1))-->(0,0,0) (0,0,1) (0,1,0) (0,1,1) (1,0,0) ...

  • str(i)[::-1]是列表切片的简写,用于反转列表。

  • 请注意所有内容是如何包装在 生成器表达式中的,它是列表推导和生成器的高性能、内存高效的泛化。

  • 另请注意,由两个 2 位数字的乘积构成的最大回文数是由数字 91 99 构成的,这两个数字是range(90,100). 外推到您可以使用的 3 位数字range(900,1000)

于 2010-02-25T13:51:02.750 回答
2

我想你会喜欢这个单行的(为便于阅读而格式化):

max(z for z in (d*e
                for d in xrange(100, 1000)
                for e in xrange(100, 1000))
            if str(z) == str(z)[::-1])

或稍作改动:

c = range(100, 1000)
max(z for z in (d*e for d in c for e in c) if str(z) == str(z)[::-1])

想知道 Lisp 中有多少个括号...

于 2010-02-24T20:28:54.770 回答