0

I'm having some trouble with iteration and keeping track of various indices and values at different points in my list (I'm new to Python).

I am running a series of cycles, but want to determine their starts and end times. Experiments starts at around 0 and end at around 50.

Here is what a list of cycles look like:

c = [0, 10, 11, 48, 50.5, 0.48, 17, 18, 23, 29, 33, 34.67, 50.1, 0.09, 7, 41, 45, 50]

Here is an example of what the output should look like:

C 1:
Start: (0, 0) # starts at index 0, value 0
End: (4, 50.5) #ends at index 4, value 50.5

C 2:
Start: (5, 0.48)
End: (12, 50.1)

C 3:
Start: (13, 0.09)
End: (17, 50)

One approach I can think of is to sort the c.

c.sort()

This will at least put all the start values at the beginning of the list and the end values at the end of the list. However, then I would lose track of their original indices. Anyone know of another approach?

EDIT:

This is what I have so far, if anyone can help modify, it would be great:

min = []
max = []
for i, (first,second) in enumerate(zip(c, c[1:])):
    print(i, first, second)
    if first < second:
        min.append(first)
        continue
    if first > second:
        max.append(first)
        continue
djennacs
  • 107
  • 1
  • 7
  • Welcome to SO. Unfortunately this isn't a discussion forum or a code writing service. Please take the time to read [ask] and the links it contains. You should spend some time working your way through [the Tutorial](https://docs.python.org/3/tutorial/index.html), practicing the examples. It will give you an introduction to the tools Python has to offer and you may even start to get ideas for solving your problem. – wwii Oct 24 '17 at 02:53
  • 1
    Use [`enumerate`](https://docs.python.org/3/library/functions.html#enumerate) – Patrick Haugh Oct 24 '17 at 02:54
  • I truly apologize, I will take a look at that tutorial now! – djennacs Oct 24 '17 at 02:54
  • thanks patrick, i'll take a look! – djennacs Oct 24 '17 at 02:55
  • So, I've discovered that using enumerate will help me obtain the indices of the list, but it's still a little hard to wrap my head around slicing the lists at the points I need to...any guidance would be really helpful. – djennacs Oct 24 '17 at 03:03
  • Have a look here on how to iterate on consecutive pairs of a list https://stackoverflow.com/questions/21303224/iterate-over-all-pairs-of-consecutive-items-from-a-given-list Inside your loop you will compare and keep them if first > second. Also you need the first and last values of your list so you have all for the output. Good luck. – thanasisp Oct 24 '17 at 03:04
  • This helpful, but using zip, as the example does, doesn't keep track of indices..still thinking about it! – djennacs Oct 24 '17 at 03:08
  • maybe combine enumerate (suggested) with zip. `enumerate(zip( ))` . or keep index track in the loop. – thanasisp Oct 24 '17 at 03:21
  • `for i, (first,second) in enumerate(zip(c, c[1:])):` – thanasisp Oct 24 '17 at 03:26
  • yup, I'm trying that. still working the best i can on it – djennacs Oct 24 '17 at 03:26

3 Answers3

0

Assuming your start value is the minimum value of the list and the end value is the maximum value of the list here's one way to do it:

(start_val,end_val) = (min(c),max(c))
(start_ind,end_ind) = (c.index(start_val),c.index(end_val))

This also assumes that the min and max values don't have duplicates or if they have, you are ok with getting the index of the first, since the index() function only returns the index of the first element it finds equal to the argument. For more info: https://docs.python.org/3.6/library/stdtypes.html#typesseq

André Santos
  • 380
  • 1
  • 4
  • 12
  • thanks, but my list has multiple start and end values as described in the question above! Starts values are close to 0, while end values are close to 50. – djennacs Oct 24 '17 at 03:16
0

Your list has increasing sequences so changes are located where a number is greater than its next. To compare all consecutive pairs of a list, you could use zip like here: Iterate over all pairs of consecutive items from a given list

Also to keep track of the list index, you can use enumerate

So here is a way to get index/value for all the start/end positions.

circle=0
for i, (first,second) in enumerate(zip(c, c[1:])):
    if i==0:
        circle +=1
        print("\nC", circle, "\nStart:", i, first)
    elif i==len(c)-2:
        print("End:", i+1, second)
    elif first > second:
        print("End:", i, first)
        circle +=1
        print("\nC", circle, "\nStart:", i+1, second)

output:

C 1 
Start: 0 0
End: 4 50.5

C 2 
Start: 5 0.48
End: 12 50.1

C 3 
Start: 13 0.09
End: 17 50
thanasisp
  • 5,855
  • 3
  • 14
  • 31
  • thank you, this was a good visualization. still having trouble visualizing my exact outputs though. i really need those. – djennacs Oct 24 '17 at 04:33
  • You can format output of print, https://docs.python.org/3/library/functions.html#print, and if you want to count the circles you print, just use an increasing variable whenever you print a start. – thanasisp Oct 24 '17 at 04:42
  • The trick is deciding how NOT to print values beyond those listen in c1, c2, and c3... – djennacs Oct 24 '17 at 04:56
  • your output works perfectly for my example here, but does not generalize to my large set of data which contains more than a couple elements in the list, so I'm still struggling with printing there. I accepted your answer because I appreciate your time, but these print statements don't generalize to larger data. – djennacs Oct 24 '17 at 05:13
  • If there is a dataset that doesn't fit, you have to provide it. Also I added a way to count the circles and print them. – thanasisp Oct 24 '17 at 05:32
0

I divide up the task, build a dictionary, D of the increasing sequences

c = [0, 10, 11, 48, 50.5, 0.48, 17, 18, 23, 29, 33, 34.67, 50.1, 0.09, 7, 41, 45, 50]

D, k = {0: []}, 0

for i, (first, second) in enumerate(zip(c, [0] + c)):
    if first >= second:
        D[k].append((i, first))  # adding increasing to value list in current D[k]
    else:
        k += 1
        D[k] = [(i, first)]  # initializing new D[k] for next sequence

then print in the desired format

for k in D:  # sorted(D) safer, dict doesn't guarantee ordering, works here  
    print('C {0}:'.format(k))
    print('Start {0}'.format(D[k][0]))
    print('End   {0}'.format(D[k][-1]), '\n')

C 0:
Start (0, 0)
End   (4, 50.5) 

C 1:
Start (5, 0.48)
End   (12, 50.1) 

C 2:
Start (13, 0.09)
End   (17, 50) 

to print the dict D nicely in my IDE I needed wider line limit

import pprint

pp = pprint.PrettyPrinter(width=100)
pp.pprint(D)

{0: [(0, 0), (1, 10), (2, 11), (3, 48), (4, 50.5)],
 1: [(5, 0.48), (6, 17), (7, 18), (8, 23), (9, 29), (10, 33), (11, 34.67), (12, 50.1)],
 2: [(13, 0.09), (14, 7), (15, 41), (16, 45), (17, 50)]}
f5r5e5d
  • 3,656
  • 3
  • 14
  • 18