2

I've found this script for linear interpolation in Python on Stack Overflow. It works perfectly well in Python 2.7, but fails in newer versions.

Here is the code:

from bisect import bisect_left class Interpolate(object): def __init__(self, x_list, y_list): if any(y - x <= 0 for x, y in zip(x_list, x_list[1:])): raise ValueError("x_list must be in strictly ascending order!") x_list = self.x_list = map(float, x_list) y_list = self.y_list = map(float, y_list) intervals = zip(x_list, x_list[1:], y_list, y_list[1:]) self.slopes = [(y2 - y1)/(x2 - x1) for x1, x2, y1, y2 in intervals] def __getitem__(self, x): i = bisect_left(self.x_list, x) - 1 return self.y_list[i] + self.slopes[i] * (x - self.x_list[i]) i = Interpolate ([0,2,3], [9,5,8]) y = i[1] 

This is the error I’m getting:

TypeError: 'Interpolate' object does not support indexing. 

What has been changed that means the code won’t work anymore?

8
  • What version of Python are you running with? I get a slightly different error with Python 3.4.1: on line intervals = zip(x_list, x_list[1:], y_list, y_list[1:]), I have TypeError: 'map' object is not subscriptable. // Oh wait, I see. Commented Apr 10, 2015 at 10:02
  • 2
    lattest time I had to do an interpolation, I used the library SciPy, which has nicely already made the function for me (aimed at scientists and numerical computing so it is bug free and efficient). docs.scipy.org/doc/scipy-0.15.1/reference/interpolate.html Commented Apr 10, 2015 at 10:07
  • 2
    Where did you find that code? Commented Apr 10, 2015 at 10:13
  • 3
    I cannot repeat the exact error code, please edit the question so that it contains the exact error and code that reproduces the error in question Commented Apr 10, 2015 at 10:19
  • 3
    You should include a reference to the question or author when you post code written by someone else: in this case the original code by Lauritz V. Thaulow is an answer to this question Commented Apr 10, 2015 at 18:24

1 Answer 1

3

This is a change to the map() function in Python 3. In Python 2.x, it would return a list, but now it returns an iterator.

Quoting from What’s New in Python 3:

map() and filter() return iterators. If you really need a list, a quick fix is e.g. list(map(...)), but a better fix is often to use a list comprehension (especially when the original code uses lambda), or rewriting the code so it doesn’t need a list at all. Particularly tricky is map() invoked for the side effects of the function; the correct transformation is to use a regular for loop (since creating a list would just be wasteful).

So the problem is occurring on these two lines:

x_list = self.x_list = map(float, x_list) y_list = self.y_list = map(float, y_list) intervals = zip(x_list, x_list[1:], y_list, y_list[1:]) 

When you try to subscript x_list and y_list when creating intervals (this is the [1:] slice), it fails because you can’t subscript an iterator.

One fix is to replace the x_list and y_list lines with these list comprehensions:

x_list = self.x_list = [float(x) for x in x_list] y_list = self.y_list = [float(y) for y in y_list] 

Not only will this allow subscripting (and so the code works as you expect), but this will still work on old versions of Python and I think it’s clearer what’s going on.

Sign up to request clarification or add additional context in comments.

5 Comments

An alternative fix is to explicitly transform the maps to lists; list(map(float, x_list)). Readability arguments could be made for either case.
I've tried using the fix like you told on both 2.7.9 and 3.4.3, alexwlchan, but it didnt help. It still works on 2.7 tho
@FilthyL Hmm. I’m using 2.7.6 and 3.4.1, and the code works fine. Could you post the entire traceback of the error? It’s possible I’m looking in the wrong place.
File "<pyshell#9>", line 1 in <module> y=i[1] TypeError: 'Interpolate' object does not support indexing
Looks like the pc is the problem, checked it on another one, works! Thanks a lot !

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.