解决方案可能相当简单,但我无法弄清楚。这是代码,它是一个简单的斐波那契数字生成器。目标是将所有均匀的斐波纳契数字总结为4,000,000以下。
我的方法是首先生成低于4,000,000的所有斐波纳契数,然后: a)用偶数生成一个新列表(“偶数”)(这很好) b)从“all”列表中删除奇数
然而,在后一种情况下,由于我不明白的原因,输出是: [2,5,8,21,34,89,144,377,610,1597,2584,6765,10946,28657,46368,121393,196418,514229,832040,2178309,3524578]
非常感谢任何帮助。谢谢!
all = []
even = []
def fibonacci():
a, b = 1, 2
while a < 4000000:
all.append(a)
a, b = b, a + b
print all
##Putting all the even fibonacci numbers in a different list and summing them up works fine
# for i in all:
# if i % 2 == 0:
# even.append(i)
# print even
# print sum(even)
# But for some strange reason I can't figure out how to remove the odd numbers from the list
for i in all:
if i % 2 != 0:
all.remove(i)
print all
print sum(all)
fibonacci()
答案 0 :(得分:4)
这是一种“陷阱”情况:您在迭代列表时从列表中删除项目,从而更改列表,导致迭代行为异常。试试这个:
...
# But for some strange reason I can't figure out how to remove the odd numbers from the list
for i in all[:]:
if i % 2 != 0:
all.remove(i)
...
这就是所谓的“切片”表示法,并使您迭代列表的一次性副本,以便您的迭代不受all.remove()调用的影响。
答案 1 :(得分:3)
您无法从迭代的列表中删除项目。 Python使用迭代器,它只知道相对于列表开头的当前索引。当您从列表的前面删除项目时,所有元素的位置都会更改,您跳过下一个元素。
您可以通过多种方式避免此问题,例如使用生成器:
def fibonacci():
a, b = 1, 2
while a < 4000000:
yield a
a, b = b, a + b
def even(seq):
for item in seq:
if item % 2 == 0:
yield item
print sum(even(fibonacci()))
答案 2 :(得分:0)
如果我们仔细观察迭代如何在以下代码中发生
for i in all:
if i % 2 != 0:
all.remove(i)
# Add these two lines for debugging..
# Or to know how this iteration functions
print "when %d: " %i
print all
print "Remaining Evens",
print all
如果最大数量为100,则输出结果如下。
original series [1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
when 1:
[2, 3, 5, 8, 13, 21, 34, 55, 89]
when 3:
[2, 5, 8, 13, 21, 34, 55, 89]
when 13:
[2, 5, 8, 21, 34, 55, 89]
when 55:
[2, 5, 8, 21, 34, 89]
Remaining Evens [2, 5, 8, 21, 34, 89]
当python开始迭代列表时,它在技术上只记住它必须迭代的数字的位置。
如果我们观察输出,
在第一次迭代中,它删除1。
在下一次迭代中,它会记住它必须计算第二个位置。现在列表从“2”开始。所以第二个位置是“3”。因此它将其删除。
在下一次迭代中,它会记住它必须从第3位开始计算。现在在当前列表中,第3个位置是“8”。所以,它从那里算起..不是从“5”。因此,如果不满足,则为13 ..
因此,它会跳过所有这些数字..
如何解决这个问题:
实际上,您需要复制“所有”列表并进行迭代。 (它不应该指同一个对象..)。如果是这样,那就会发生同样的事情。
你可以通过简单地使用切片操作符来做到这一点:
copy_all= all[:]
#or else, you need to use deepcopy()
import copy
copy_all = copy.deepcopy(all)
# you iterate copy_all but delete in all.
However, prefer the first method. Its very simple.
答案 3 :(得分:-1)
这是因为你删除索引i处的项目而不是数字“i”。