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

2018-01-02 10:03:21 +08:00
 seabottom1978

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 不知道哪里写错了?

1991 次点击
所在节点    Python
7 条回复
freeminder
2018-01-02 10:14:17 +08:00
for a,b in range(1,n+1)
freeminder
2018-01-02 10:15:20 +08:00
不小心发出去了,range 返回一个 int,你这里对一个 int 拆包成 a,b 两个变量,所以提示你 int 无法遍历
seabottom1978
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
2018-01-02 10:26:18 +08:00
是的,太谢谢了
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
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
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 -> []

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/419288

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX