英文:
Loop gets stuck on the third index
问题
以下是翻译好的部分:
"Good day. I need to make a function that returns a sum of the two lowest positive integers in the list.
It didn't work out so I've made it print its each step and then I saw that it gets stuck on the third index for some reason. It says 'list index out of range' but I can't quite understand why is it if there are 5 positions in the list. Can't figure it out on my own.
def sum_two_smallest_numbers(numbers):
a = 2147483647
numers = numbers
b = a
for i in range(0, len(numbers)):
print(numbers[i])
if numbers[i] < a and numbers[i] > 0:
a = numbers[i]
numbers.pop(i)
for j in range(0, len(numers)):
if numers[j] < b and numers[j] > 0:
b = numers[j]
numers.pop(j)
return a + b
print(sum_two_smallest_numbers([19, 5, 42, 2, 77]))
英文:
Good day. I need to make a function that returns a sum of the two lowest positive integers in the list.
It didn't work out so I've made it print its each step and then I saw that it gets stuck on the third index for some reason. It says 'list index out of range' but I can't quite understand why is it if there are 5 positions in the list. Can't figute it out on my own.
def sum_two_smallest_numbers(numbers):
a = 2147483647
numers = numbers
b = a
for i in range(0, len(numbers)):
print(numbers[i])
if numbers[i] < a and numbers[i] > 0:
a = numbers[i]
numbers.pop(i)
for j in range(0, len(numers)):
if numers[j] < b and numers[j] > 0:
b = numers[j]
numers.pop(j)
return a + b
print(sum_two_smallest_numbers([19, 5, 42, 2, 77]))
</details>
# 答案1
**得分**: 2
`pop`从列表中移除一个值,因此每次使用`pop`时,您的列表长度都会减少,目前您正在使用这个算法从列表中删除数字。
```python
def sum_two_smallest_numbers(numbers):
a = 2147483647
numers = numbers
b = a
ind = -1
for i in range(0, len(numbers)):
if numbers[i] < a and numbers[i] > 0:
a = numbers[i]
ind = i
numbers.pop(ind)
for j in range(0, len(numbers)-1):
if numers[j] < b and numers[j] > 0:
b = numers[j]
return a + b
print(sum_two_smallest_numbers([19, 5, 42, 2, 77]))
请注意,此算法假定您的列表中至少有2个正数。另外,还有更高效的方法可以使用仅一个for
循环来完成这个任务。
英文:
pop
removes a value from the list so each time you use pop
the length of your list gets shorter and right now you keep deleting numbers from your list using this algorithm.
def sum_two_smallest_numbers(numbers):
a = 2147483647
numers = numbers
b = a
ind = -1
for i in range(0, len(numbers)):
# print(numbers[i])
if numbers[i] < a and numbers[i] > 0:
a = numbers[i]
ind = i
numbers.pop(ind)
for j in range(0, len(numbers)-1):
if numers[j] < b and numers[j] > 0:
b = numers[j]
return a + b
print(sum_two_smallest_numbers([19, 5, 42, 2, 77]))
Note that this algorithm assumes there are at least 2 positive numbers in your list. Also, there are more efficient ways to do this with only one for loop.
答案2
得分: 2
这段代码的翻译如下:
这段代码有效。
a = [-1, 2, 34, 22, 4]
a = [i for i in a if i > 0]
first_min = min(a)
a.remove(first_min)
second_min = min(a)
print(first_min + second_min)
英文:
This works.
a = [-1, 2, 34, 22, 4]
a = [i for i in a if i > 0]
first_min = min(a)
a.remove(first_min)
second_min = min(a)
print(first_min+second_min)
答案3
得分: 1
首先,规则是在迭代列表时永远不要修改它。您试图通过使用索引来绕过这个规则,但是在开始循环之前计算范围,然后从列表中删除元素=>这样一来,您会得到一个大于或等于列表大小的索引。
此外,您将删除比最小值更多的元素。让我们假设我们修复了上面的错误,看看会发生什么:
- 第一次迭代:19小于2147483647:a = 19 并且19从列表中删除
- 下一个:5小于19:再次a = 5 并且5被删除,这是不好的,因为它是第二小的元素!
所以,您至少应该更改您的算法,只删除最终的最小元素:
def sum_two_smallest_numbers(numbers):
a = 2147483647
numers = numbers
b = a
for i in range(0, len(numbers)):
print(numbers[i])
if numbers[i] < a and numbers[i] > 0:
a = numbers[i]
numbers.remove(a)
for j in range(0, len(numers)):
if numers[j] < b and numers[j] > 0:
b = numers[j]
numers.remove(b)
return a + b
print(sum_two_smallest_numbers([19, 5, 42, 2, 77]))
但这不符合Python的习惯用法,因为Python列表是可迭代的,并且不高效,因为您需要两次迭代数组。以下是更好的方法:
def sum_two_smallest_numbers(numbers):
a = b = 2147483647 # a和b将是两个最小的元素
for i in numbers:
print(i)
if i < b: # 如果i >= b:则什么都不用做
if i < a: # 新元素是当前最小的
b = a
a = i
else: # 新元素是当前第二小的
b = i
# 如果希望作为副作用从数组中删除元素,请取消注释下面两行
# numbers.remove(a)
# numbers.remove(b)
return a + b
英文:
First the rule is never modify a list while iterating on it. You are trying to circumvent it by using indices, but you compute the range before starting the loop and then remove elements from the list => at a time you get an index that is greater or equal than the size of the list.
In addition, you will remove more elements than the smallest one. Let us assume that we fixed the above error and see what happens
- first iteration: 19 is less than 2147483647: a = 19 and 19 is removed from the list
- next: 5 is less that 19: again a = 5 and 5 is removed which is bad because it is the second smallest element !
So you should at least change your algo to only remove the final smallest element:
def sum_two_smallest_numbers(numbers):
a = 2147483647
numers = numbers
b = a
for i in range(0, len(numbers)):
print(numbers[i])
if numbers[i] < a and numbers[i] > 0:
a = numbers[i]
numbers.remove(a)
for j in range(0, len(numers)):
if numers[j] < b and numers[j] > 0:
b = numers[j]
numers.remove(b)
return a + b
print(sum_two_smallest_numbers([19, 5, 42, 2, 77]))
But this is un-pythonic because Python lists are iterable, and not efficient because you iterate the array twice. This would be better:
def sum_two_smallest_numbers(numbers):
a = b = 2147483647 # a and b will be the 2 smallest elements
for i in numbers:
print(i)
if i < b: # if i >= b : nothing to do
if i < a: # new element is the current smallest
b = a
a = i
else: # new element is the current second smallest
b = i
# uncomment both following line if you want to remove the elements from the array
# as a side effect
# numbers.remove(a)
# numbers.remove(b)
return a + b
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论