471,337 Members | 896 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,337 software developers and data experts.

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 1414
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

Post your reply

Sign in to post your reply or Sign up for a free account.

Similar topics

21 posts views Thread by Hilde Roth | last post: by
6 posts views Thread by Michael Drumheller | last post: by
12 posts views Thread by Steven Bethard | last post: by
10 posts views Thread by Ishwor | last post: by
108 posts views Thread by Bryan Olson | last post: by
6 posts views Thread by Derek Peschel | last post: by
3 posts views Thread by Rüdiger Werner | last post: by
reply views Thread by rosydwin | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.