2015-01-11 2 views
-1

У меня есть список из 60 элементов, CashFlow. Я создаю новый список ListNPV, где каждый элемент является результатом уравнения, использующего каждый элемент исходного CashFlow. После добавления суммы в новый список я удаляю один элемент из исходного CashFlow.Почему моя петля в цикле печатает только половину длины списка?

Когда я запустил это, он завершает ровно половину списка, поэтому 30 значений. Я удвоил код, чтобы убедиться, и это приводит к 15/45 по сравнению с 30/30. Я хочу 0/60. Использование Canopy.

for payment in CashFlow: 
    NPV = 0 
    for i in range(len(CashFlow)):  
     NPV += CashFlow[i]/(1+MonthlyInterest)**i 
     NPV = round (NPV, 0) 
    ListNPV.append(NPV) 
    CashFlow.remove(payment) 
print 'CashFlow = ', CashFlow 
print 'ListNPV =', ListNPV 
+1

На каком языке Вы говорите? Он * выглядит * как Python, но ... Кроме того, почему вы считаете, что это лучший подход для этого? Вы мутируете тот же список, который вы повторяете, что во многих случаях является плохой практикой. – Makoto

+0

Это Python, используя новую среду Canopy. Это было лучшее, что я мог придумать, оценил бы другие идеи. –

ответ

2

От the python docs, вы не должны изменять список вы итерация:

Если вам необходимо изменить последовательность вы итерация в то время как внутри цикл (например, дублировать выбранные элементы), его рекомендуется , чтобы вы сначала сделали копию. Итерация по последовательности не неявно делает копию.

В этом случае вы даже не используете переменную цикла, payment, так что вы можете просто немного очистить петли. Это должно работать:

N = len(CashFlow) 
for j in range(N): 
    NPV = 0 
    for i in range(j, N): 
     NPV += CashFlow[i]/(1+MonthlyInterest) ** (i - j) 
     NPV = round (NPV, 0) 
    ListNPV.append(NPV) 

print 'CashFlow = ', CashFlow 
print 'ListNPV =', ListNPV 
+0

Genius. Спасибо! –

+0

Итерация с 'j = 1' и' i = 0' приведет к отрицательной силе '(1 + MonthlyInterest) ** (i - j)' части уравнения, которого не было в OP. EDIT: О, я вижу, что это невозможно, отличное решение. – dopstar

1

Благодаря следуя линии

CashFlow.remove(payment) 

Выше линии воздействиях длина CashFlow.Remove этой линии, и все ваши итерации будет сделано. После этого вы можете удалить список денежных потоков отдельно.

+0

Право - но мне нужно рассчитать новое дополнение к ListNPV на основе CashFlow минус один элемент. –

+0

Для этого скопируйте все содержимое CashFlow в другую коллекцию, а затем зациклируйте на одну коллекцию, которая не должна оставаться неизменной, и измените другую коллекцию и вычислите ее. Зацикливание и изменение одной и той же коллекции приводит к тому, что случаи трудно отлаживать и исправлять. – Tilak