V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
seabottom1978
V2EX  ›  Python

列表生成式的调试?(题目要求计算 1 至 n(包括 n)间有 a,b 两数, a,b 的乘积等于 1 至 n 总和减 a,减 b(如果 n=26,返回 15,21 或者 21,15))

  •  
  •   seabottom1978 · 2018-01-02 10:03:21 +08:00 · 2094 次点击
    这是一个创建于 2520 天前的主题,其中的信息可能已经有所发展或是发生改变。

    def removNb(n): result = [] for a in range(1, n+1): for b in range(1, n+1): if sum(range(1, n+1))-(a+b)==a*b: result.append((a,b)) return result

    我把这段代码用列表生成式表达为 def removNb(n): return [(a,b) for a,b in range(1,n+1) if sum(range(1,n+1))-(a+b)==a*b] 得到的错误提示是:TypeError: 'int' object is not iterable 不知道哪里写错了?

    7 条回复    2018-01-02 18:08:14 +08:00
    freeminder
        1
    freeminder  
       2018-01-02 10:14:17 +08:00
    for a,b in range(1,n+1)
    freeminder
        2
    freeminder  
       2018-01-02 10:15:20 +08:00
    不小心发出去了,range 返回一个 int,你这里对一个 int 拆包成 a,b 两个变量,所以提示你 int 无法遍历
    seabottom1978
        3
    seabottom1978  
    OP
       2018-01-02 10:23:27 +08:00
    那么必须用 2 层循环?[(a,b) for a in range(1,n+1) for b in range(1,n+1) if sum(range(1,n+1))-(a+b)==a*b]
    seabottom1978
        4
    seabottom1978  
    OP
       2018-01-02 10:26:18 +08:00
    是的,太谢谢了
    Kilerd
        5
    Kilerd  
       2018-01-02 12:06:55 +08:00
    lambda n: [a for a in range(int(n/2), n+1) if int((n*n + n + 2)/2/(a+1)) == (n*n + n + 2)/2/(a+1)]
    hl
        6
    hl  
       2018-01-02 16:07:23 +08:00
    问题简化出来就是一个多元一次方程求可能解的问题,使用等差数列求和公式省掉不必要的循环

    我提供一个我的思路:
    1、生成 1~n 排列组合 list。 形式如[(1,1),(1,2),(1,3),(2,2),(2,3),(3,3)]
    2、if 条件判断 排列组合列表内 tuple 元素 a,b 的乘积与总和减 a,b 是否相等,相等则返回
    3、使用内建 filter 函数获得结果

    =====filter 函数=====
    filter(function, sequence):
    对 sequence 中的 item 依次执行 function(item),将执行结果为 True 的 item 组成一个 List/String/Tuple (取决于 sequence 的类型)返回


    ====用到两个东西==
    1、python 内置的可重复排列组合函数 combinations_with_replacement()
    2、1 至 n 总和 使用等差数列求和公式 Sn = n*a1 + n* (n – 1)*d/2 ( n 为项数,a1 为第一个数,d 为公差)

    ===公式补充说明===
    等差数列求和公式:Sn = n*a1 + n* (n – 1)*d/2
    n 为项数,d 为公差,在题主场景里由于是从 1 开始以 1 递增,且公差为 1,公式可以简化为:
    Sn = n + n* (n – 1)/2


    =======实现======
    ```python3
    from itertools import combinations_with_replacement

    def findPossible(n):
    sn = range(1,n+1) #生成等差数列
    combList = list(combinations_with_replacement(sn,2)) #生成排列组合列表

    result = filter(lambda item: equationJudge(n, sn,item), combList) #对 combList 进行逐项 filter
    return list(result)

    def equationJudge(n, sn, t):
    snLength = len(sn)
    if t[0]*t[1] == snLength + snLength * ( n - 1 ) / 2 - t[0] - t[1]: #套用公式
    return t

    possibleNum = findPossible(26)

    print (possibleNum)
    ```
    xpresslink
        7
    xpresslink  
       2018-01-02 18:08:14 +08:00
    from itertools import combinations as combs

    def solution(n): return list(filter(lambda c: c[0]*c[1] == sum(range(1,n+1))-sum(c), combs(range(1,n+1), 2)))

    for i in range(30): print(i, '->', solution(i))

    0 -> []
    1 -> []
    2 -> []
    3 -> []
    4 -> []
    5 -> []
    6 -> []
    7 -> []
    8 -> []
    9 -> []
    10 -> [(6, 7)]
    11 -> []
    12 -> []
    13 -> []
    14 -> []
    15 -> []
    16 -> []
    17 -> [(10, 13)]
    18 -> []
    19 -> []
    20 -> []
    21 -> []
    22 -> []
    23 -> []
    24 -> []
    25 -> []
    26 -> [(15, 21)]
    27 -> []
    28 -> []
    29 -> []
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3264 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 14:06 · PVG 22:06 · LAX 06:06 · JFK 09:06
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.