Python-如何计算一个区间内(包括边界)所有奇数的和?

3

我需要写一个程序,用户输入两个数字,然后它会给出该范围内所有奇数的和加上用户输入的2个数字。我搜索了很多,但没有找到包含界限的任何内容。到目前为止,我有:

x=int(input('Enter first number: '))
y=int(input('Enter second number: '))

def SumOdds(x,y):
  count=0
  for i in range(x,y):
     if (int(i%2==1)):
        count=count+i

  print(count)
SumOdds(x,y)

这段代码计算了奇数的总和,但并未包括输入数字本身。例如,如果我输入10和20,代码会输出75,但实际上结果应该是105(75+10+20)。我相信这个问题很容易解决,但由于我刚开始学习Python,所以需要你的帮助。谢谢!


使用range(x,y+1) - Sheldore
你应该添加“奇数”边界吗?在这里,你只需要添加边界,无论它们是偶数还是奇数。 - Willem Van Onsem
你可以在某个地方使用 + x + y 这样的东西,怎么样? - mkrieger1
sum([i for i in range(x,y+1) if i%2]) - Arthur Julião
9个回答

2

所以你只需要在for循环结束后加上两个数字即可。试试这个:

x=int(input('Enter first number: '))
y=int(input('Enter second number: '))

def SumOdds(x,y+1):
  count= x + y #notice instead of 0, it's the sum now!
  for i in range(x,y):
     if(i == x or i == y):
         pass
     elif (int(i%2==1)):
        count=count+i

  print(count)
SumOdds(x,y)

编辑:根据您的评论,如果限制条件是奇数,则不需要将其添加两次。 y+1 确保您捕获整个范围,并且检查 i == x or i == y 跳过该范围内的这些值,因为我们已经在开始时添加了它们。


谢谢!当两个输入都是偶数时,这个程序可以正常工作,但当它们都是奇数时,它会再次添加x的值。例如:我输入11和21。它给了我107,尽管应该是96。 - rbku
那么,您不想重复添加限制,是吧? - Capn Jack
不考虑 x 或 y 是否为奇数。如果 x 或 y 是偶数,它应该仍然计算它们,但如果其中任何一个是奇数,它只应该计算一次。这样说清楚了吗? - rbku
太好了!我就知道这是一些简单的东西哈哈。感谢你的帮助。 - rbku
@rbku,很高兴它对你有用,也是个好问题!如果你愿意将我的答案标记为已接受的答案(点击投票按钮旁边的复选标志),它将有助于未来的读者看到这个解决方案对你有用。 - Capn Jack

1

仅单独检查边界。

x=int(input('Enter first number: '))
y=int(input('Enter second number: '))

def SumOdds(x,y):
  count=0
  for i in range(x,y):
    if (int(i%2==1)):
      count=count+i
  if(x%2==0):
    count= count+x
  if(y%2==0):
    count= count+7
  print(count)
SumOdds(x,y)

基本循环应包括任何奇数限制,因此只有在限制为奇数时才需要添加限制。

1
range(..) 对象中,“上限”(第二个参数)是“排除”的。因此,为了解决这个问题,只需使用 range(x, y+1) 即可,例如:
def SumOdds(x, y):
    count=0
    for i in range(x, y+1):
        if i%2==1:
            count=count+i
    print(count)

SumOdds(x,y)

请注意,我们可以提高速度,因为这个总和可以用一个公式来计算:
 n
---
\                   2     2
/    2*i + 1 = (n+1)   - m
---
i=m

所以我们可以把这个计算为:
def sumOdds(x, y):
    m = x//2
    n1 = ((y-1)//2)+1
    print(max(0, n1*n1 - m*m))

这种方法的优点是对于小到不太大的数字,它的运行时间为O(1),对于巨大的数字,它的运行时间为O(log m + log n)(因为乘法可能需要更长时间)。因此,我们可以相当快速地计算出巨大数字的总和,例如:
>>> timeit.timeit(lambda: SumOdds(12345678901234567890, 98765432109876543210), number=1000000)
0.5030524220055668

因此,在 12'345'678'901'234'567'890 和 98'765'432'109'876'543'210 之间计算奇数元素的总和只需 503 纳秒。迭代方法将需要线性时间,并且可能无法在合理的时间内获得结果。


1
首先,我会将范围扩展到 y+1,然后在该范围内取所有的奇数,接着我会检查 xy 是否都是偶数,如果是,我会将它们加入列表中。
x = int(input('Enter first number: '))
y = int(input('Enter second number: '))
tot = [i for i in range(x, y+1) if i % 2]

if not x % 2:
    tot.append(x)

if not y % 2:
    tot.append(y)

print(sum(tot))

0
你应该将范围的第二个数字增加一,因为 Python 范围的工作方式是包括第一个数字但不包括最后一个数字。然后按照您所做的方式计算奇数的总和,并在最后将两个输入的数字与您的奇数总和相加。您可以为此创建一个新变量(如下所示),也可以将其添加到奇数总和变量中。
x1=int(input('Enter first number: '))
x2=int(input('Enter second number: '))

def sum_odds(x1, x2):
    odd_sum = 0
    total_sum = 0
    for number in range(x1, x2+1):
        if number % 2 != 0:
            odd_sum+=number
    total_sum = odd_sum + x1 + x2
    print(total_sum)

    return total_sum

sum_odds(x1,x2)

0

我感觉可能有些地方我没理解对 - 你已经将端点作为参数传入了,那为什么不将它们加入计数中呢?

x=int(input('Enter first number: '))
print x
y=int(input('Enter second number: '))
print y

def SumOdds(x,y):
  count = x + y

  # x + 1 for an exclusive range, i.e (10, 20) will check the numbers 11-19
  for i in range(x+1, y):
     if (int(i % 2 ==1 )):
        count= count + i

  print(count)
SumOdds(x,y)

在线尝试!

此外,通过列表推导的魔力,如果您愿意,可以将那个for循环缩减为一行:

x=int(input('Enter first number: '))
y=int(input('Enter second number: '))

def SumOdds(x,y):
  # x + y + each i in range 11-19, if i is odd
  count = x + y + sum(i for i in range(x+1, y) if i % 2 == 1)
  print(count)
SumOdds(x,y)

在线试用!


0

sum([i for i in range(x, y+1) if not i%2==0])

这不够吗?


0
为了避免重复添加限制,你也可以使用集合。虽然乍一看不简单,但它可以使你的代码更优雅。
x=int(input('Enter first number: '))
y=int(input('Enter second number: '))

def sum_odds_and_limits(x,y):
    to_sum = set() #sets are collections of unique elements
    to_sum |= {x,y} #union
    for num in range(x,y+1):
        if num%2==1 :
            to_sum|={num}
    print(sum(to_sum))

sum_odds_and_limits(x,y)

为了提高效率,建议您在循环中避免使用模数(%)和条件。在Python中,切片符号是一个很好的工具:

range(x,y+1)[(x+1)%2::2]
#list()[<start position>:<ending position>:<take every N element>]

你会最终得到类似以下的代码:
x=int(input('Enter first number: '))
y=int(input('Enter second number: '))

def sum_odds_and_limits(x,y):
    #sum all the odd numbers and boundaries in the given range
    to_sum = set(range(x,y+1)[(x+1)%2::2])
    to_sum |= {x,y}
    print(sum(to_sum))

sum_odds_and_limits(x,y)

我坚持让函数名称清晰易懂。但这是个人习惯。


0
也许我们可以简化一下... 试试这个。
>> start = int(input("Enter the start of range: "))

>> end = int(input("Enter the end of range: "))

>> tot = [n for n in range(start, end+1) if n%2] or [n for n in range(start, end+1) if not n%2]

>> print("your odd numbers are")

>> print(tot, end = "")

>> print ("and their sum is their sum is")

>> print(sum(tot))`

1
你能否在这个答案中添加一些示例输入和输出,以使其更清晰明了? - jmp
我尝试将较小的数字设为0,较大的数字设为100,执行了这个示例……它列出了0到100之间所有的奇数,并将它们的和作为2500返回。 - Sinelk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接