user1640255
user1640255

Reputation: 1304

Python loop define limits trouble

I am newbie in Python ... I am dealing with an array of 10 elements A[0,10] trying to do this loop:

for i in range(1, 9):
    C.append((A[i+1]-A[i-1])/2)

to find the average value of each point...

afterwards If I wish to print the results :

print(i, A[i], C[i])
print(i, A[i], C[i-2])

the second print is only working, the first is not.. please why this? And I need also to define the first and the last value of C[1] and C[10] and I can't do that because the first value is the C[-2] which is C[9] ...

if someone has any idea how to solve it....

Upvotes: 0

Views: 395

Answers (3)

jfs
jfs

Reputation: 414139

You use symmetric difference to find C but the edge points (0,9) have only one neighbor. You could fix it by using left, right differences for edge points:

n = len(A) # 10 in your case
C = [0.] * n

if n > 1:
   C[0] = (A[1] - A[0]) / 2.
   C[-1] = (A[-1] - A[-2]) / 2.

for i in xrange(1, n-1):
    C[i] = (A[i+1] - A[i-1]) / 2.

Whether it is appropriate depends on how you'd like to use the C list later.

If you need C[0] = C[1] then it is even simpler:

n = len(A)
C = [0.] * n

for i in xrange(1, n-1):
    C[i] = (A[i+1] - A[i-1]) / 2.

if n > 1:
   C[0] = C[1]
   C[-1] = C[-2] # for symmetry

if n == 0 i.e., A is empty then C is empty.

if n == 1 i.e., A has exactly one element then C has exactly one element: C[0] = 0.

Upvotes: 1

Marcin
Marcin

Reputation: 49816

It's not usual to iterate over python lists (and I assume you mean a list) by index. You're operating on pairs of items, so a more idiomatic way to do this would be:

for prev, next in zip(a, a[2:]):
    # do whatever

Look up zip in the standard documentation. The two variables are assigned from the results of zip using sequence assignment, which is just where a comma-separated list of variables is bound to the elements of a sequence.

The second thing you're doing that is unidiomatic is to append to a list in a loop. This sort of thing is so common that python has a specific syntax for it:

[(next - prev)/2 for prev, next in zip(a, a[2:])]

This is called a list comprehension. If you can't guess what that does after pasting it into the interpreter, read about it in the standard documentation and the many articles available via google.

That code in action;

>>> import random
>>> a = range(5,15)
>>> random.shuffle(a)
>>> a
[11, 5, 12, 14, 6, 7, 8, 13, 10, 9]
>>> [(next - prev)/2 for prev, next in zip(a, a[2:])]
[0, 4, -3, -4, 1, 3, 1, -2]
>>>

Upvotes: 2

Hugh Bothwell
Hugh Bothwell

Reputation: 56624

Python lists are always indexed starting at 0. If you do

c = []         # c is a list
c.append(3)    # append 3 to the end of the list
print c        # => [3]
print c[0]     # => 3

So your code is putting (A[0]+A[2])/2 into C[0], then (A[1]+A[3])/2 into C[1], etc.

You might want create C as a list containing the appropriate number of 0s first, like

c = [0.]*10    # create a 10-item list

# calculate smoothed values from a
for i in xrange(1,9):
    c[i] = 0.25*a[i-1] + 0.5*a[i] + 0.25*a[i+2]

# clean up the ends
c[0] = 0.75*a[0] + 0.25*a[1]
c[9] = 0.25*a[8] + 0.75*a[9]

Upvotes: 0

Related Questions