0

I have a list of including some cost values for a project. The list c says that a project started in year 1 (assuming c[0] = year 1, suspended in year 3, and completed at the end of year 4. So, there is no associated cost in year 5.

c = [3000000.0, 3000000.0, 0.0, 200000.0, 0.0]

From the list, I want to find the project length, which is basically 4 not 3 in the above example based on my way of programming. If the list would be as following:

d = [3000000.0, 3000000.0, 100000.0, 200000.0, 0.0]

I could have the following to solve my problem:

Input:

cc = 0
for i in d:
    if i>0:
        cc += 1

Output:
cc = 4

However, it does not really work when there is a suspension(gap) between two years. Any suggestions to make it work?

tcokyasar
  • 582
  • 1
  • 9
  • 26

5 Answers5

2

So, you want to find the position of last 0 in the list. Look at this question

What I think is the best approach from the link above is:
last_0 = max(loc for loc, val in enumerate(c) if val == 0)

You can also calculate the first 0: first_0 = min(loc for loc, val in enumerate(c) if val == 0)

And their difference is the length.

In one block:

zeros_indices = [loc for loc, val in enumerate(c) if val == 0]
length = max(zeros_indices) - min(zeros_indices)
Neo
  • 3,534
  • 2
  • 20
  • 32
1

if you want to find the last index + 1 (index start to 0) which is not 0 you can do :

>>> c = [3000000.0, 3000000.0, 0.0, 200000.0, 0.0, 0.0]
>>> cc=[c.index(i) for i in c if i!=0][-1]+1
>>> cc
4

EDIT :

you can use numpy to not take in account the first 0 in the list:

>>> c = [0.0, 0.0, 3000000.0, 3000000.0, 0.0, 200000.0, 0.0, 0.0]
>>> import numpy as np
>>> np.trim_zeros(c)
[3000000.0, 3000000.0, 0.0, 200000.0]
>>> len(np.trim_zeros(c))
4
Dadep
  • 2,796
  • 5
  • 27
  • 40
  • This is what I want. Thank you @Dadep. – tcokyasar Sep 28 '17 at 16:59
  • Actually, it is not also working. See the example: `c = [0.0, 0.0, 3000000.0, 200000.0, 0.0]` Output: `4`. However, based on my logic, it should be `2`. – tcokyasar Sep 28 '17 at 17:04
  • Great! Thank you very very much Dadep. You saved me a lot of time. Otherwise, I was gonna apply my method I mentioned to @gogaz. – tcokyasar Sep 28 '17 at 17:14
0

You could look backwards through the list until you find the index of an element which has a value greater than zero, and if you add one to that index it will be the length in years with gaps allowed.

Rach Sharp
  • 2,324
  • 14
  • 31
0

To include gap years to your counting, you can check that the current item is not the last one in the list.

You would better do this by iterating over indexes instead of elements to avoid having to find out your position within the list at each iteration.

cc = 0
for i in xrange(len(c)):
    if c[i] > 0 and i < (len(c) - 1):
        cc += 1

The xrange function generates a list from 0 to len(c). You could eihter use range instead but range keeps the generated list in memory while xrange does not.

EDIT: This does not handle multiple zeros at the end of the list c

gogaz
  • 2,323
  • 2
  • 23
  • 31
  • Input: `c = [3000000.0, 0.0, 0.0, 0.0, 200000.0]` Output: 1. However, I am expecting 5 that is why not working. – tcokyasar Sep 28 '17 at 17:01
  • This is true but not mentionned in your question – gogaz Sep 28 '17 at 17:02
  • I thought "suspended in year 3" means: 0 cost is counted after the project started. Actually, while answering this, I got how the logic should be programmed. First, I need to search for the starting year, where the first value>0 is the starting point in the list. Then, I find the last value>0 in the list. The range gives me the project length. – tcokyasar Sep 28 '17 at 17:11
0
c = [3000000.0, 3000000.0, 0.0, 0.0, 200000.0, 0.0]

cc = 0
templength = 0
for i in reversed(c):
  if i == 0:
    templength += 1
  else:
    break
print (len(c)-templength)

output:

5
prudhvi Indana
  • 789
  • 7
  • 19