IndexError:列表索引超出范围,拍摄方法

时间:2022-10-29 16:40:34
x1=np.linspace(xmin, xmax, Nsteps)
y1=np.linspace(0., 0., Nsteps)
h=x1[1]-x1[0]
V1=-V0*np.exp(-alpha*(x1)**2)
E=-1
k=math.sqrt(-2*E)
y1[0]=1
y1[1]=np.exp(k*h)
f=2*[V1-E]

def a():
   for i in range (1,Nsteps):
    denom = np.sum(2+10*h**2*f[i]/12)
    numer = np.sum(1-h**2*f[i+1]/12)   
    return denom/numer


def b():
  for i in range(1, Nsteps):
    denom = np.sum(1-h**2*f[i-1]/12)
    numer = np.sum(1-h**2*f[i+1]/12)
    return denom/numer

def y2():
    a[i]*y1[i] + b[i]*y1[i-1]

for i in range (1, Nsteps):
    print(y2)

plt.plot(x1, y2)
plt.show()

For some given parameters, my goal is to produce a code that implements the shooting method. However, when running it i get the IndexError due to different lengths of x1 and y2. My boundaries for i are 1 and 1001. I assume that at the boundaries f[i-1] and f[i+1] produce values that are out of the defined range? Also when running the last for-loop, am I running the previous for-loops again within that for-loop and therefore creating something strange? Those are my guesses, and my second question would be if there is a trick for solving that issue? Can I implement some if-condition to correct this?

对于某些给定的参数,我的目标是生成实现拍摄方法的代码。但是,在运行它时,由于x1和y2的长度不同,我得到了IndexError。我对i的界限是1和1001.我假设在边界f [i-1]和f [i + 1]产生超出定义范围的值?另外,当运行最后一个for循环时,我是否在for循环中再次运行先前的for循环,因此创建了一些奇怪的东西?这些是我的猜测,我的第二个问题是,如果有一个解决这个问题的技巧?我可以实现一些if条件来纠正这个问题吗?

1 个解决方案

#1


0  

There are a number of issues with your code, first and foremost of which is readability. This isn't the 70s where bytes are expensive - add whitespace to your statements so you can see what's going on. In that same vein, name your variables and functions appropriately. How is a reader supposed to know what a() does? As an example, turn this:

您的代码存在许多问题,首先是可读性问题。这不是字节很贵的70年代 - 在你的陈述中添加空格,这样你就可以看到发生了什么。同样,请适当地命名变量和函数。读者如何知道a()的作用?举个例子,转过来:

V1=-V0*np.exp(-alpha*(x1)**2)

into this:

V1 = -V0 * np.exp(-alpha * (x1**2))

It's much easier to see what's going on.

看到发生的事情要容易得多。

Next, use 4 spaces for indentation, and use it consistently - you can see potential indentation issues much more easily - such as the fact that in a() and b() you have return inside the for loop, causing it to only run once. All good programming editors (that is, pretty much everything besides Windows Notepad) allow you to set what is inserted when you hit the Tab key. Mixing tabs and spaces is an error in Python 3, so just don't use tab characters (\t) at all.

接下来,使用4个空格进行缩进,并始终如一地使用它 - 您可以更容易地看到潜在的缩进问题 - 例如,在()和b()中你已经在for循环内返回,导致它只运行一次。所有优秀的编程编辑器(除了Windows Notepad之外的几乎所有内容)都允许您设置按Tab键时插入的内容。在Python 3中混合制表符和空格是一个错误,所以根本不要使用制表符(\ t)。

In y2(), a[i] and b[i] don't make sense because a and b are functions, which cannot be sliced like that, and i is not defined in this context.

在y2()中,a [i]和b [i]没有意义,因为a和b是函数,不能像那样切片,并且我没有在此上下文中定义。

print(y2) will print something like <function y2 at 0x7fae9e8e3378>, which I'm pretty sure is not what you want to do. Similarly, plt.plot(x1, y2) will not do what you want. If you refactor y2() to actually return something (it doesn't currently) and that something is either a list or a NumPy array corresponding to the contents of x1, then you should use plt.plot(x1, y2()) instead.

print(y2)将打印类似 的内容,我很确定这不是你想要做的。同样,plt.plot(x1,y2)也不会做你想要的。如果你重构y2()实际返回一些东西(它当前没有),并且某些东西是一个列表或一个对应于x1内容的NumPy数组,那么你应该使用plt.plot(x1,y2())代替。

Put all this into practice, and you'll still have to refactor (and rename) a() and b() so that they calculate and return the value(s) you want them to. Remember that while functions can read variables defined in the same scope the function is defined in, it is a much better idea to explicitly pass the objects you want the function to work on via arguments. So, instead of:

将所有这些付诸实践,你仍然需要重构(和重命名)a()和b(),以便他们计算并返回你想要的值。请记住,虽然函数可以读取定义函数的同一作用域中定义的变量,但是通过参数显式传递您希望函数处理的对象是一个更好的主意。所以,而不是:

some_lst = [1, 2, 3, 4, 5]
some_str = "abcde"

def zippem():
    return list(zip(some_lst, some_str))

You should use:

你应该使用:

some_lst = [1, 2, 3, 4, 5]
some_str = "abcde"

def zippem(input_a, input_b):
    return list(zip(input_a, input_b))

then call it like so:

然后这样称呼它:

list_o_tuples = zippem(some_lst, some_str)

This allows you to move the function definition to a different module, put it in a class, or just function with arbitrary input instead of the defined objects in its scope.

这允许您将函数定义移动到不同的模块,将其放在类中,或者只使用任意输入而不是其范围中定义的对象。

#1


0  

There are a number of issues with your code, first and foremost of which is readability. This isn't the 70s where bytes are expensive - add whitespace to your statements so you can see what's going on. In that same vein, name your variables and functions appropriately. How is a reader supposed to know what a() does? As an example, turn this:

您的代码存在许多问题,首先是可读性问题。这不是字节很贵的70年代 - 在你的陈述中添加空格,这样你就可以看到发生了什么。同样,请适当地命名变量和函数。读者如何知道a()的作用?举个例子,转过来:

V1=-V0*np.exp(-alpha*(x1)**2)

into this:

V1 = -V0 * np.exp(-alpha * (x1**2))

It's much easier to see what's going on.

看到发生的事情要容易得多。

Next, use 4 spaces for indentation, and use it consistently - you can see potential indentation issues much more easily - such as the fact that in a() and b() you have return inside the for loop, causing it to only run once. All good programming editors (that is, pretty much everything besides Windows Notepad) allow you to set what is inserted when you hit the Tab key. Mixing tabs and spaces is an error in Python 3, so just don't use tab characters (\t) at all.

接下来,使用4个空格进行缩进,并始终如一地使用它 - 您可以更容易地看到潜在的缩进问题 - 例如,在()和b()中你已经在for循环内返回,导致它只运行一次。所有优秀的编程编辑器(除了Windows Notepad之外的几乎所有内容)都允许您设置按Tab键时插入的内容。在Python 3中混合制表符和空格是一个错误,所以根本不要使用制表符(\ t)。

In y2(), a[i] and b[i] don't make sense because a and b are functions, which cannot be sliced like that, and i is not defined in this context.

在y2()中,a [i]和b [i]没有意义,因为a和b是函数,不能像那样切片,并且我没有在此上下文中定义。

print(y2) will print something like <function y2 at 0x7fae9e8e3378>, which I'm pretty sure is not what you want to do. Similarly, plt.plot(x1, y2) will not do what you want. If you refactor y2() to actually return something (it doesn't currently) and that something is either a list or a NumPy array corresponding to the contents of x1, then you should use plt.plot(x1, y2()) instead.

print(y2)将打印类似 的内容,我很确定这不是你想要做的。同样,plt.plot(x1,y2)也不会做你想要的。如果你重构y2()实际返回一些东西(它当前没有),并且某些东西是一个列表或一个对应于x1内容的NumPy数组,那么你应该使用plt.plot(x1,y2())代替。

Put all this into practice, and you'll still have to refactor (and rename) a() and b() so that they calculate and return the value(s) you want them to. Remember that while functions can read variables defined in the same scope the function is defined in, it is a much better idea to explicitly pass the objects you want the function to work on via arguments. So, instead of:

将所有这些付诸实践,你仍然需要重构(和重命名)a()和b(),以便他们计算并返回你想要的值。请记住,虽然函数可以读取定义函数的同一作用域中定义的变量,但是通过参数显式传递您希望函数处理的对象是一个更好的主意。所以,而不是:

some_lst = [1, 2, 3, 4, 5]
some_str = "abcde"

def zippem():
    return list(zip(some_lst, some_str))

You should use:

你应该使用:

some_lst = [1, 2, 3, 4, 5]
some_str = "abcde"

def zippem(input_a, input_b):
    return list(zip(input_a, input_b))

then call it like so:

然后这样称呼它:

list_o_tuples = zippem(some_lst, some_str)

This allows you to move the function definition to a different module, put it in a class, or just function with arbitrary input instead of the defined objects in its scope.

这允许您将函数定义移动到不同的模块,将其放在类中,或者只使用任意输入而不是其范围中定义的对象。