0

What I have:

vec=[{'max': 23.425, 'date': u'2017-07-18', 'ismax': False, 'ismin': False, 'min': 14.615}, 
     {'max': 23.83, 'date': u'2017-07-19', 'ismax': False, 'ismin': False, 'min': 14.765}, 
     {'max': 24.07, 'date': u'2017-07-20', 'ismax': False, 'ismin': False, 'min': 14.985}]

Now I want to find the overall minimum and maximum; i've tried doing this:

mini=min(vec[:]['min'])
maxi=max(vec[:]['max'])

But it says:

Type error indexes must be integers not str

I knew that colon stands for 'cycle across all the indices' so what am I doing wrong?

cs95
  • 379,657
  • 97
  • 704
  • 746
DDS
  • 2,340
  • 16
  • 34

3 Answers3

6

vec[:] just makes a copy of the list. So vec[:]['min'] tries to lookup 'min' in the copy, but that doesn't work as list indices must be integers.

Good job for a generator expression:

mini = min(v['min'] for v in vec)
RemcoGerlich
  • 30,470
  • 6
  • 61
  • 79
2

You can also use the min and max function with a key argument:

In [966]: max(vec, key=lambda x: x['max'])['max']
Out[966]: 24.07

In [967]: min(vec, key=lambda x: x['min'])['min']
Out[967]: 14.615

You can speed this up a bit using operator.itemgetter.

Using these functions with a key returns the entire sub-dict containing the max/min, so you'd need to use indexing to retrieve just the value you want.


Timings:

Setup: vec = [{ 'max' : random.randint(1, 1000), 'min' : random.randint(1, 1000)} for x in range(100000)]

# @RemcoGerlich's solution
In [990]: %timeit min(v['min'] for v in vec)
100 loops, best of 3: 10.8 ms per loop

# proposed in this post
In [991]: %timeit min(vec, key=operator.itemgetter('min'))['min']
100 loops, best of 3: 9.19 ms per loop
Community
  • 1
  • 1
cs95
  • 379,657
  • 97
  • 704
  • 746
2

Simply make use of the key param in min()/max() function

min(vec, key=lambda x: x['min'])
max(vec, key=lambda x: x['max'])

the min() one gives:

{'ismin': False, 'min': 14.615, 'date': '2017-07-18', 'ismax': False, 'max': 23.425}

Click the above link to python doc for detailed info.

Chazeon
  • 546
  • 2
  • 14