2015-11-30 122 views
1
def sum_div(x, y): 
    for k in range(x,y+1): 
     for z in range(x,y+1): 
      sx = 0 
      sy = 0 
      for i in range(1, k+1): 
       if k % i == 0: 
        sx += i 
      for j in range(1, z+1): 
       if z % j == 0: 
        sy += j 
      if sx == sy and k!= z: 
       print "(", k ,",", z, ")" 

x = input("Dati x : ") 
y = input("Dati y : ") 
sum_div(x, y) 

如何停止的z == y的循环,如果价值?如何停止循环?

的循环打印一对数字的范围从xy,但是当它击中y值循环打印相反对,我并不需要它的数字。

+1

为什么你的for循环范围具体包括y,你期望'while y''做什么? – user2357112

+2

'如果z == y:break'? –

+0

行踪和你想打破哪个循环? –

回答

1

你是什么觉得你所要求的是break命令,但你实际上寻找的是去除重复的。

你的程序缺少一些清晰度。例如:

for i in range(1, k+1): 
    if k % i == 0: 
     sx += i 
for j in range(1, z+1): 
    if z % j == 0: 
     sy += j 

这两件事情基本上做同样的事情,它可以用list comprehension更干净写入(在REPL):

>>> def get_divisors(r: int) -> list: 
...  return [i if r % i == 0 else 0 for i in range(1, r+1)] 
... 
... 
>>> get_divisors(4) 
>>> [1, 2, 0, 4] 

>>> sum(get_divisors(4)) 
>>> 7 

你行:

while y: 

...如果你找到一个匹配将会无限循环。你应该删除它。 while y的意思是“while y is true”,其中的任何值都会评估为true。

这将减少你的程序如下:

def get_divisors(r: int) -> list: 
    return [i if r % i == 0 else 0 for i in range(1, r+1)] 

def sum_div(x, y): 
    for k in range(x,y+1): 
     sum_of_x_divisors = sum(get_divisors(k)) # Note this is moved here to avoid repeating work. 
     for z in range(x,y+1): 
      sum_of_y_divisors = sum(get_divisors(z)) 
      if sum_of_x_divisors == sum_of_y_divisors and k!= z: 
       print("({},{})".format(k, z)) 

测试这个在REPL这似乎是正确的基于代码的逻辑:

>>> sum_div(9,15) 
(14,15) 
(15,14) 
>>> sum_div(21, 35) 
(21,31) 
(31,21) 
(33,35) 
(35,33) 

但它可能是为sum_div(9,15)你想只有一个(14,15)(15,14)。但是,这与打破循环无关,但当kz彼此不相等时,您尝试执行的操作有两个有效值。第二个测试用例说明了这一点,其中(33,35)是一个重复的值,但如果您打破(21,31)的for循环,则不会获得第二组值。我们可以解释这种

的方法之一是重新排序时,工作就完成了:

def sum_div(x, y): 
    result_set = set() # Sets cannot have duplicate values 
    for k in range(x,y+1): 
     sum_of_x_divisors = sum(get_divisors(k)) 
     for z in range(x,y+1): 
      sum_of_y_divisors = sum(get_divisors(z)) 
      if sum_of_x_divisors == sum_of_y_divisors and k!= z: 
       result_set.add(tuple(sorted((k,z)))) # compile the result set by sorting it and casting to a tuple, so duplicates are implicitly removed. 
    for k, z in result_set: # Print result set after it's been compiled 
     print("({},{})".format(k, z)) 

而且我们看到一个正确的结果:

>>> sum_div(9,15) 
(14,15) 
>>> sum_div(21,35) 
(21,31) 
(33,35) 

或者,您在留言中提供的测试案例。注意缺乏重复的:

>>> sum_div(10,25) 
(16,25) 
(14,15) 
(15,23) 
(10,17) 
(14,23) 

一些外卖:

  • 摆脱这一正在做同样的事情功能,使您可以更轻松地推论它。
  • 以人类可读的格式命名变量,以便我们,您的代码的读者(包括您)了解发生了什么。
  • 不要使用循环,除非你实际上循环了一些东西。 for,while等只需要使用,如果你打算去检查一系列事情。
  • 在提问时,一定要包括测试输入,预期输出和实际回收的内容。
  • print ing字符串的当前最佳做法是使用.format() function,以清楚地表明要打印的内容。
+0

感谢您的回答,但事情是我不需要反向的(14,15) (15,14)我得到了相同的输出,我需要的是停止循环打印反向的... –

+0

查看我的更新。你不需要停止循环,你需要以某种方式忽略该值:'sum_div(21,35)'将停止循环*太快*如果你只是打破了...除非你只是试图找到一个解决方案。这是*为什么*您需要提供输入值和预期输出:上面提出的问题不是您实际寻找的解决方案。 –

+0

@FrederickCastello再次更新了我的答案,以解决您的问题,这真的是一个积累,而不是循环中断。 –

3

break命令将跳出循环。所以这样的一条线:

if (z == y): 
    break 

应该做你想做的。

+0

不,我试过了,这不起作用... –

+0

这将取决于你放在哪里它,因为它只会打破最内层循环。 –

+0

回路制动器可以打印的唯一地方是打印前“(”,k,“,”,z,“)” –