简体   繁体   English

看来我的代码正在无限循环

[英]It seems my code is making an infinite loop

I'm a python learner and It seems my code is making an infinite loop in the while expression, but I don't understand why.我是一名 Python 学习者,似乎我的代码在while表达式中进行了无限循环,但我不明白为什么。

What I want is a program to sum the first five odd numbers in this list.我想要的是一个程序来总结这个列表中的前五个奇数。

This is a very basic exercise in Udacity site, the output was program shut down for using 13 CPU seconds and in the Windows python3 it doesn't show any output.这是 Udacity 站点中一个非常基本的练习,输出是程序关闭使用 13 个 CPU 秒,而在 Windows python3 中它不显示任何输出。 After some tests, my suspicion is a problem with an infinite loop in the while expression.经过一些测试,我怀疑是while表达式中存在无限循环的问题。

num_list = [422, 136, 524, 85, 96, 719, 85, 92, 10, 17, 312, 542, 87, 23, 86, 191, 116, 35, 173, 45, 149, 59, 84, 69, 113, 166]

    z=0
    s=0
    for i in range(len(num_list)):
        while z<=5:
            if num_list[i]%2==1:
                z+=1
                s+=num_list[i]
    print(s)

Follow your code按照你的代码

  • you start index 0你开始索引0
  • read value is 422读取值为422
  • you don't go into the if你没有进入如果
  • you don't increase z你不增加z
  • you stays in the while loop for infinite你无限期地停留在while循环中
for i in range(len(num_list)):
    while z <= 5:
        if num_list[i] % 2 == 1:

Solution 1 : don't use 2 loops (while and for) because you want to do 2 things : iterate iver the values and check the 5 conditions.解决方案 1 :不要使用 2 个循环(while 和 for),因为您想做两件事:迭代值检查 5 个条件。 You may just use a break when you got five当你得到五个时,你可以break

for i in range(len(num_list)):
    if num_list[i] % 2 == 1:
        z += 1
        s += num_list[i]
    if z >= 5:
        break

Solution 2 : use a different logic解决方案 2 :使用不同的逻辑

  • get the odd ones得到奇怪的
  • get the first 5 of them获得前 5 个
  • sum them将它们相加
r = sum(list(filter(lambda i: i % 2 == 1, num_list))[:5])

your for loop will put the first item of num_list into i so i will be 422 .您的 for 循环会将num_list的第一项放入i因此i将是422 you then have a while loop that will run for as long as z<=5 .然后你有一个 while 循环,只要z<=5就会运行。

You then check if 422 % 2 is equal to 1. Its not 422 mod 2 is 0. So since this condition is not true, you never update z so z will always remain as 0. And since 0 is less than 5 your loop will run forever然后您检查422 % 2是否等于 1。它不是 422 mod 2 是 0。因此,由于此条件不成立,因此您永远不会更新 z,因此 z 将始终保持为 0。并且由于 0 小于 5,您的循环将永远运行

The problem is that if num_list[i]%2==1: does not trigger.问题是if num_list[i]%2==1:不会触发。 This prevents both the for and while loop conditions from changing, trapping the execution in the inner loop.这可以防止forwhile循环条件发生变化,从而将执行困在内部循环中。

The first change to avoid an infinite loop is avoiding the loop itself.避免无限循环的第一个变化是避免循环本身。 Since the count of odd numbers should be checked only once per number, use if instead of while .由于每个数字只应检查奇数的计数,因此请使用if而不是while

z=0
s=0
for i in range(len(num_list)):
    if z<=5:  # checked only once for each i
        if num_list[i]%2==1:
            z+=1
            s+=num_list[i]
print(s)

This will already fix your problem.这已经可以解决您的问题。 You may want to clean up your code further, though.不过,您可能希望进一步清理代码。 Writing idiomatic code will naturally avoid certain pitfalls, such as infinite loops.编写惯用代码自然会避免某些陷阱,例如无限循环。

First, consider that the two checks have separate purpose.首先,考虑这两项检查有不同的目的。 The z check exists to halt iteration, the %2 check to select elements. z检查用于停止迭代, %2检查用于选择元素。 Halting iteration is done using break .停止迭代是使用break完成的。

z=0
s=0
for i in range(len(num_list)):
    if z<=5:  # break condition
        break
    if num_list[i]%2==1:  # sum condition
        z+=1
        s+=num_list[i]
print(s)

Now, keep in mind that Python's container types are iterable by themselves.现在,请记住 Python 的容器类型本身是可迭代的。 There is no need for a separate i index, numbers can be fetched directly from the list.不需要单独的i索引,可以直接从列表中获取数字。 Also, keep in mind that non-zero numbers are considered "true" – instead of num % 2 == 1 , check only for num %2 .另外,请记住,非零数字被认为是“真”——而不是num % 2 == 1 ,只检查num %2

z=0
s=0
for number in num_list:  # iterate on elements, eliminate i
    if z <= 5:
        break
    if number % 2:  # only test that it is not zero
        z += 1
        s += number
print(s)

Python has several tools to simplify working with iterables. Python 有多种工具可以简化可迭代对象的使用。 A generator expression allows to cheaply filter and transform an iterable.生成器表达式允许廉价地过滤和转换可迭代对象。 This allows to remove all even numbers before the for loop.这允许在for循环之前删除所有偶数。

z=0
s=0
# only work on odd numbers
for odd_number in (num for num in num_list if num % 2):
    if z <= 5:
        break
    z += 1
    s += odd_number
print(s)

Since increasing an iteration count is so common, Python has a builtin to do that for you: enumerate .由于增加迭代次数非常普遍,Python 有一个内置函数可以为您执行此操作: enumerate It takes an iterable, and counts up as new items are fetched.它需要一个可迭代对象,并在获取新项目时计数。

s=0
# automatically calculate z
for z, odd_number in enumerate(num for num in num_list if num % 2):
    if z == 5:
        break
    s += odd_number
print(s)

In this case, the only purpose of z is to select the first 5 elements.在这种情况下, z的唯一目的是选择前 5 个元素。 Whenever you need to work with "the first n" or "the last m" items, consider to use slicing.每当您需要处理“前 n”或“最后 m”项时,请考虑使用切片。 Slicing is used on containers using container[start:stop:step] syntax, or on arbitrary iterables using itertools.islice .切片用于使用container[start:stop:step]语法的container[start:stop:step] ,或使用itertools.islice任意迭代器。

from itertools import islice

s=0
# only use the first 5 odd numbers                             V
for odd_number in islice((num for num in num_list if num % 2), 5):
    s += odd_number
print(s)

Finally, summing up an iterable is also a very common task, and Python has a builtin for that as well: sum .最后,总结一个迭代也是一项非常常见的任务,Python 也有一个内置的: sum Since by now the entire logic has been shifted from the loop to the iterable, it can be summed up in one go.由于现在整个逻辑已经从循环转移到可迭代的,所以可以一口气总结。

s = sum(islice((num for num in num_list if num % 2), 5))
print(s)

Hope this helps希望这可以帮助

num_list = [422, 136, 524, 85, 96, 719, 85, 92, 10, 17, 312, 542, 87, 23, 86, 191, 116, 35, 173, 45, 149, 59, 84, 69, 113, 166]
c = 0
sum_ = 0
for number in num_list:
    if (c > 4 ):
        break
    if (number % 2 == 1):
        sum_ += number
        c+=1
print(sum_)

prints印刷

993

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM