将嵌套的Python循环转换为列表推导式

3 投票
3 回答
4885 浏览
提问于 2025-04-15 19:41

我开始做一些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]或者类似的结果。

有没有Python高手能帮帮我?:)

3 个回答

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语言中会有多少个括号吗……

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] 是一种简便的列表切片方法,用来反转一个列表。

  • 注意所有内容都被包裹在一个 生成器表达式 中,这是一种高效且省内存的列表推导和生成器的扩展。

  • 还要注意,两个两位数相乘得到的最大回文数是由 91 和 99 这两个数字组成的,它们都在 range(90,100) 这个范围内。如果推导到三位数,你可以使用 range(900,1000)

7

在编程中,有时候我们会遇到一些问题,特别是在使用某些工具或库的时候。比如,有人可能会在使用某个特定的功能时,发现它并没有按照预期工作。这种情况可能是因为设置不正确,或者是使用的版本不兼容。

解决这类问题的第一步通常是检查文档,看看是否有说明或者提示。文档就像是使用说明书,可以帮助我们理解如何正确使用这些工具。

另外,很多时候,社区的讨论也能提供帮助。像StackOverflow这样的平台,很多开发者会分享他们的经验和解决方案。通过搜索相关的问题,我们可能会找到别人遇到过类似的情况,并且他们是如何解决的。

总之,遇到问题时,不要慌张,先查文档,再看看社区的讨论,通常能找到解决办法。

c = range(a, b)
print [d * e for d in c for e in c]

撰写回答