473,247 Members | 2,869 Online

# indexing in a list

Say I have this list

Expand|Select|Wrap|Line Numbers
1. prices = [100.0, 90.0, 90.0, 93.0, 92.0, 80.0, 92.0, 87.0, 83.0, 75.0, 80.0, 70.0, 83.0, 75.0, 80.0, 90.0, 92.0, 85.0]
I created a new list that starts from the low point of the list like so

Expand|Select|Wrap|Line Numbers
1. Right = prices.index(min(prices))
2. midpoint = (min(prices) + max(prices))/2
3. rightprices = prices[right:]
4. print rightprices
[83.0, 75.0, 80.0, 90.0, 92.0, 85.0]

Now I want to cut it up again, but this time taking the numbers the only occur after the midpoint, which should be 85.

How can I get a list that just yields the elements in the list from as soon as a number >= midpoint, thus leaving me with just 90, 82, 85

The way I was doing it before, looks for exactly a certain number (such as the min(price)), if I could only get a greater than clause in there… I tried

Leftover = prices.index(>=midpoint), but that didn't fly.

Any suggestions, ideas, etc?

Thanks
Sep 14 '07 #1
7 1563
bartonc
6,596 Expert 4TB
List comprehensions will be your best friend forever, once you get the hang of them:
Expand|Select|Wrap|Line Numbers
1. >>> [x for x in prices if x > 83]
2. [100.0, 90.0, 90.0, 93.0, 92.0, 92.0, 87.0, 90.0, 92.0, 85.0]
3. >>>
Sep 14 '07 #2
that's it...kinda.

if i were to add a number to the end of the list, say 20. I'd also want that in the list, because I want all the numbers after a number in the list >= median.

So to do that I was thinking, if I did your method, which would exclude points after the numbers dip below the medium, then I could look for the index of the 1st number in the list. The slice from there...right?

here's what I got and it seems to work.

Expand|Select|Wrap|Line Numbers
1. a = [83.0, 75.0, 80.0, 90.0, 92.0, 85.0, 20.0, 99.0]
2. stuff = [x for x in a if x >= median]
3. newlist = a.index(stuff[0])
4. leftovers = a[newlist:]
leftovers = [90.0, 92.0, 85.0, 20, 99]

BUT
is there a prettier (more pythonic) way to do it?
Sep 14 '07 #3
ghostdog74
511 Expert 256MB
if you are doing medians, you should sort the data first ,isn't it?
Expand|Select|Wrap|Line Numbers
1. >>> prices
2. [100.0, 90.0, 90.0, 93.0, 92.0, 80.0, 92.0, 87.0, 83.0, 75.0, 80.0, 70.0, 83.0, 75.0, 80.0, 90.0, 92.0, 85.0]
3. >>> sorted_prices = sorted(prices)
4. >>> sorted_prices
5. [70.0, 75.0, 75.0, 80.0, 80.0, 80.0, 83.0, 83.0, 85.0, 87.0, 90.0, 90.0, 90.0, 92.0, 92.0, 92.0, 93.0, 100.0]
6. >>> median=sorted_prices[len(sorted_prices)/2]
7. >>> print median
8. 87.0
9. >>> [i for i in sorted_prices if i > median ]
10. [90.0, 90.0, 90.0, 92.0, 92.0, 92.0, 93.0, 100.0, 90]
11.
Sep 15 '07 #4
bvdet
2,851 Expert Mod 2GB
if you are doing medians, you should sort the data first ,isn't it?
Expand|Select|Wrap|Line Numbers
1. >>> prices
2. [100.0, 90.0, 90.0, 93.0, 92.0, 80.0, 92.0, 87.0, 83.0, 75.0, 80.0, 70.0, 83.0, 75.0, 80.0, 90.0, 92.0, 85.0]
3. >>> sorted_prices = sorted(prices)
4. >>> sorted_prices
5. [70.0, 75.0, 75.0, 80.0, 80.0, 80.0, 83.0, 83.0, 85.0, 87.0, 90.0, 90.0, 90.0, 92.0, 92.0, 92.0, 93.0, 100.0]
6. >>> median=sorted_prices[len(sorted_prices)/2]
7. >>> print median
8. 87.0
9. >>> [i for i in sorted_prices if i > median ]
10. [90.0, 90.0, 90.0, 92.0, 92.0, 92.0, 93.0, 100.0, 90]
11.
You are correct GD. Adding to that, if the length of the sample is an even number, there is no distinct median value. The median value would then be the mean of the two middle values.
Expand|Select|Wrap|Line Numbers
1. def median(s):
2.     i = len(s)
3.     if i%2:
4.         # integer division (e.g. 19/2 = 9)
5.         return (s[i/2]+s[(i/2)+1])/2.0
6.     return s[i/2]
7.
8. prices = [100.0, 90.0, 90.0, 93.0, 92.0, 80.0, 92.0, 87.0, 83.0, 75.0, 80.0, 70.0, 83.0, 75.0, 80.0, 90.0, 92.0, 85.0, 20.0]
9.
10. print [i for i in sorted(prices) if i > median(sorted(prices))]
>>> [87.0, 90.0, 90.0, 90.0, 92.0, 92.0, 92.0, 93.0, 100.0]
Sep 16 '07 #5
bartonc
6,596 Expert 4TB
You are correct GD. Adding to that, if the length of the sample is an even number, there is no distinct median value. The median value would then be the mean of the two middle values.
Expand|Select|Wrap|Line Numbers
1. def median(s):
2.     i = len(s)
3.     if i%2:
4.         # integer division (e.g. 19/2 = 9)
5.         return (s[i/2]+s[(i/2)+1])/2.0
6.     return s[i/2]
7.
8. prices = [100.0, 90.0, 90.0, 93.0, 92.0, 80.0, 92.0, 87.0, 83.0, 75.0, 80.0, 70.0, 83.0, 75.0, 80.0, 90.0, 92.0, 85.0, 20.0]
9.
10. print [i for i in sorted(prices) if i > median(sorted(prices))]
>>> [87.0, 90.0, 90.0, 90.0, 92.0, 92.0, 92.0, 93.0, 100.0]
Looking at this, I see the list being sorted twice for every element in the list...
I think that patrickc was on the right path in finding the median first:
Expand|Select|Wrap|Line Numbers
1. >>> prices = [100.0, 90.0, 90.0, 93.0, 92.0, 80.0, 92.0, 87.0, 83.0, 75.0, 80.0, 70.0, 83.0, 75.0, 80.0, 90.0, 92.0, 85.0]
2. >>> def median(floatList):
3. ...     return sum(floatList)/len(floatList)
4. ...
5. >>> median(prices)
6. 85.388888888888886
7. >>>
Then apply the list comprehension.
Sep 16 '07 #6
bvdet
2,851 Expert Mod 2GB
Looking at this, I see the list being sorted twice for every element in the list...
I think that patrickc was on the right path in finding the median first:
Expand|Select|Wrap|Line Numbers
1. >>> prices = [100.0, 90.0, 90.0, 93.0, 92.0, 80.0, 92.0, 87.0, 83.0, 75.0, 80.0, 70.0, 83.0, 75.0, 80.0, 90.0, 92.0, 85.0]
2. >>> def median(floatList):
3. ...     return sum(floatList)/len(floatList)
4. ...
5. >>> median(prices)
6. 85.388888888888886
7. >>>
Then apply the list comprehension.
Normally you would design your code to sort a list only once, which I did not do.
Expand|Select|Wrap|Line Numbers
1. prices = [100.0, 90.0, 90.0, 93.0, 92.0, 80.0, 92.0, 87.0, 83.0, 75.0, 80.0, 70.0, 83.0, 75.0, 80.0, 90.0, 92.0, 85.0, 20.0]
2. prices.sort()
3. print [i for i in prices if i > median(prices)]
Your function median() calculates the arithmetic mean or average. The median of a list is the middle value of the list after sorting, meaning there are an equal number of values above and below the median.
Sep 16 '07 #7
bartonc
6,596 Expert 4TB
Normally you would design your code to sort a list only once, which I did not do.
Expand|Select|Wrap|Line Numbers
1. prices = [100.0, 90.0, 90.0, 93.0, 92.0, 80.0, 92.0, 87.0, 83.0, 75.0, 80.0, 70.0, 83.0, 75.0, 80.0, 90.0, 92.0, 85.0, 20.0]
2. prices.sort()
3. print [i for i in prices if i > median(prices)]
Your function median() calculates the arithmetic mean or average. The median of a list is the middle value of the list after sorting, meaning there are an equal number of values above and below the median.
Yeah... I didn't pass math... Thanks for straightening me out there.
Sep 16 '07 #8