How to calculate numbers in a list [duplicate] - python

This question already has answers here:
Python: Finding differences between elements of a list
(12 answers)
Difference between consecutive elements in list [duplicate]
(3 answers)
Closed 4 years ago.
here is my code.
A = [86.14803712, 85.25496701, 86.50334271, 86.0266668, 86.61455594, 86.90445213, 86.65519315, 87.10116762, 87.08173861]
B = []
i = 0
for i in range(len(A)):
c = A[i]-A[i-1]
B.append(c)
print(c)
I want to get the differences between two continuous numbers in this list, eg,(85.25496701-86.14803712). So in the results, I should have eight numbers as results.
But the results I get are:
-0.9337014900000042
-0.8930701099999965
1.2483756999999969
-0.4766759099999973
0.5878891400000015
0.2898961899999932
-0.24925897999999336
0.4459744699999959
-0.019429009999996083
I don't need -0.9337014900000042 since it comes from the first number subtract the last number in the list. What should I do the fix it? Thanks

That's the strength and the weakness of python: index -1 is always valid when the list isn't empty, which can lead to programs not crashing but not doing what you want.
For those operations, it's better to use zip to interleave the list with a sliced version of itself without the first number:
A = [86.14803712, 85.25496701, 86.50334271, 86.0266668, 86.61455594, 86.90445213, 86.65519315, 87.10116762, 87.08173861]
diffs = [ac-ap for ac,ap in zip(A[1:],A)]
or with itertools.islice to avoid creating a new list to iterate on it:
import itertools
diffs = [ac-ap for ac,ap in zip(itertools.islice(A,1,None),A)]
result (8 values):
[-0.8930701099999965, 1.2483756999999969, -0.4766759099999973, 0.5878891400000015, 0.2898961899999932, -0.24925897999999336, 0.4459744699999959, -0.019429009999996083]

It's possible to do this in base Python, but you might like the semantic clarity of Pandas:
import pandas as pd
pd.Series(A).diff().values[1:]
array([-0.89307011, 1.2483757 , -0.47667591, 0.58788914, 0.28989619,
-0.24925898, 0.44597447, -0.01942901])

You can just do:
B = [x-y for x, y in zip(A[1:], A)]
print(B) # -> [-0.8930701099999965, 1.2483756999999969, -0.4766759099999973, 0.5878891400000015, 0.2898961899999932, -0.24925897999999336, 0.4459744699999959, -0.019429009999996083]

You need to make sure you star from a correct index. In your current code, in the first iteration of the loop you will be computing A[0] - A[-1]. Hence, you need to start i from 1 to ensure in the first iteration you compute the value of A[1] - A[0]. The corrected version of your code is here:
A = [86.14803712, 85.25496701, 86.50334271, 86.0266668, 86.61455594, 86.90445213, 86.65519315, 87.10116762, 87.08173861]
B = []
i = 0
for i in range(1, len(A)):
c = A[i]-A[i-1]
B.append(c)
print(c)

I think the problem is that the loop subtracts the first element to the last because the loop starts at index 0 and subtracts it from index -1 (python takes -1 as the last index of a list). A better solution imo would be:
A = [86.14803712, 85.25496701, 86.50334271, 86.0266668, 86.61455594,
86.90445213, 86.65519315, 87.10116762, 87.08173861]
B = []
i = 0
for i in range(len(A)-1):
c = -(A[i]-A[i+1])
B.append(c)
print(c)

The easiest would be:
result = [x-y for x,y in zip(A[1:], A[:-1])]

Related

Changing elements of a list of lists [duplicate]

This question already has answers here:
How to add 1 to every element of a matrix / nested list in Python?
(4 answers)
Closed 1 year ago.
I need to add 0.05 to elements of coords array. But nothing happens.
Can you advise me where is the mistake? (I thought this would be easy but no)
coords = [[0.1,0.1,0.1],
[0.2,0.2,0.2],
[0.3,0.3,0.3]]
for i in coords:
for j in i:
j = j+0.05
print(coords)
Your solution doesn't actually modify the elements in the list by iterating over j. You could try a double list comprehension like this:
coords[:] = [j+0.05 for i in coords for j in i]
This has the advantage of editing the original object without creating a new instance of a list.
You current way will not store the results, as you did not provide a list to hold the results. I can show you two more straightforward examples:
a = [1,2,3,4]
for number in a:
number = number + 1
# check results
# nothing happens
print(a)
But if you do:
# you will get results
b = [number + 1 for number in a]
print(b)
The only difference is that you need to provide a list to hold the data.
Try this:
coords = [[0.1,0.1,0.1],
[0.2,0.2,0.2],
[0.3,0.3,0.3]]
for i in range(len(coords)):
for j in range(len(coords[i])):
coords[i][j] += .05
print(coords)
You can use lst comprehension
coords = [[0.1,0.1,0.1],
[0.2,0.2,0.2],
[0.3,0.3,0.3]]
newCoords = [[num+0.05 for num in lst] for lst in coords ]
print(newCoords)

How to create list and initialize only some of it's values in Python (in comparison to C++)

I need to create an List of size N and then initialize only N-1th and N-2th elements only. Which means if the size of the list is 5 then it should only contain elements in 3rd and 4th position.
i know how to do it in C++ but is there any way to implement it in Python?
for example: In C++
int *n = new int[5];
n[3] = 20
n[4] = 10
//and if we print the output it will show some garbage values in index 0, 1, 2 and will print 20 10 which is the values we initailized
How can i do it in python? or anything similar to this!
In python, list must be initialized with values.
Closest thing you can do:
N = 5
lst = [0] * (N-2) + [20, 10]
This:
Fills the N-2 elements of a list with default value 0
Sets the value for the last two elements
Concatenates the zeros and last two elements sub-lists of stages 1 & 2
In python,
array=[]
length=5
for i in range(length):
array.append(0)
array[3]=20
array[4]=10
Edit: As pointed out by kabanus, a more efficient way to do this would be-
array=[0]*length
Instead of the for loop.

Python slicing behavior using for loop

I am trying to use a for loop to create a series from entries in a dataframe, however I am having difficulties getting the last element of the dataframe.
import pandas as pd
a = pd.DataFrame([0,1,2,3,4,5,6,7])
a.values[-1] # returns 7
a.values[-5:-1]# returns 3,4,5,6
a.values[-5:]# returns 3,4,5,6,7
b = []
for i in range(0,len(a)):
b.append(a.values[-(i+1):-i])
I would like for 7 to be included in the list b. I realize that when i=0, a.values gives an empty array, however I'm not sure how to fix this as I can't iterate i to be blank as shown above.
Why not just manually convert negative indices to positive indices?
for i in range(0, len(a)):
b.append(a.values[(len(a) - (i+1) - 1):(len(a) - i)])
This works because python doesn't care if your upper limit in a slice is out-of-bounds, so long as the lower-limit is in bounds.
But if you're just trying to reverse the list (which it seems like you're trying to do), have you considered b = reversed(a)?
I would like for 7 to be included in the list b
import pandas as pd
a = pd.DataFrame([0,1,2,3,4,5,6,7])
b = []
for i in range(0, len(a)):
b.append(a.iloc[i])
OR, As a one-liner:
b = [a.iloc[i] for i in range(0, len(a))]
This will remove the blank and include 7 in the list:
for i in range(0,len(a)):
b.append(a.values[-i-1])

How to get mean from list that is partially empty example [0,2,4,0,4,0,0,0,0,10] [duplicate]

This question already has answers here:
Computing average of non-zero values
(3 answers)
Closed 3 years ago.
How to get mean from list that is partially empty example [0,2,4,0,4,0,0,0,0,10]
So mean should be (2+4+4+10)/4 = 5 , but statistics.mean() divides by the overall amount of numbers in the list (which in this case is 10).
So in my case I need to get mean from the list of numbers which are divisible by 3 (list b)
import random
import statistics
a = []
b = []
c = [0,2,4,0,4,0,0,0,0,10]
for x in range (10):
a.append(random.randint(0,101))
for x in a:
if x%3==0:
b.append(x)
else:
b.append(0)
average = statistics.mean(b)
print('a',a)
print('b',b)
print('Srednia',average)
You can filter out the zeros from the list using a for-loop perhaps
from statistics import mean
c = [0,2,4,0,4,0,0,0,0,10]
#Filter out 0's
non_zero_c = [item for item in c if item]
#Calculate mean from non zero numbers
print(mean(non_zero_c))
The output will be 5
In alternative to creating a list of only non-zero elements you can count them
non_zero_mean = sum(x) / sum(element != 0 for element in x)
here I'm using the "trick" that from a math point of view in Python (like in C and C++) True == 1 and False == 0.
Another alternative is
non_zero_mean = sum(x) / (len(x) - x.count(0))
Very quickly, the easiest way is to use some list comprehension to select the part of the list that interest you.
Example:
"How to get mean from list that is partially empty example [0,2,4,0,4,0,0,0,0,10] "
a = [0,2,4,0,4,0,0,0,0,10]
a_selection = [elt for elt in a if elt != 0]
m = sum(a_selection)/len(a_selection)
Same for divisible by 3:
b_selected = [elt for elt in b if elt%3==0]

Separate elements of array into two arrays [duplicate]

This question already has answers here:
How to remove items from a list while iterating?
(25 answers)
Closed 5 years ago.
I did one simple code to separate elements of an array into two new arrays : one with odd numbers and other with even numbers. So I did this:
V=[1,2,3,4,5,6]
vp=[]
vi=[]
for x in V:
if x%2==0:
vp.append(x)
V.remove(x)
else:
vi.append(x)
V.remove(x)
print (V)
print (vp)
print (vi) # sorry for the bad identation first time sharing code here
and this code give me this result:
[2,4,6]
[]
[1,3,5]
How is it happen? How am I fix this?
You shouldn't remove item while traversing an array:
V=[1,2,3,4,5,6]
vp=[]
vi=[]
for x in V:
if x%2==0:
vp.append(x)
else:
vi.append(x)
Modifying a list mid-iteration causes misbehavior (you effectively skip input elements). Don't remove from V as you go (which for long V would be expensive, each remove is O(n) making total work O(n**2)), just leave V unmodified. If necessary, clear V when you finish (a single O(n) operation), e.g. after the loop:
del V[:]
When you remove items from a list, the list gets shorter. So when you're looping over a list in a forward direction, removing items will cause the the iterator to skip forward.
To mitigate this, you can loop backwards over a list and safely remove items, since you're removing them from the end.
V = [1,2,3,4,5,6]
vp = []
vi = []
# reverse the list before iterating
for x in reversed(V):
if x % 2 == 0:
vp.append(x)
V.remove(x)
else:
vi.append(x)
V.remove(x)
Other answers that identified the problem and the fix, but here is a different way to do it using list comprehensions.
numbers = [1,2,3,4,5,6]
even = [e for e in numbers if e % 2 == 0]
odd = [e for e in numbers if e % 2 == 1]
A more concise way to make a new odd and even list from the original is to use comprehensions:
v = [1,2,3,4,5,6]
even = [number for number in v if number % 2 == 0]
odd = [number for number in v if number % 2 != 0]
Don't remove items from a list over which you are iterating. Use a copy:
V=[1,2,3,4,5,6]
vp=[]
vi=[]
for x in V[:]:
if x%2==0:
vp.append(x)
V.remove(x)
else:
vi.append(x)
V.remove(x)
print (V)
print (vp)
print (vi)
# []
# [2, 4, 6]
# [1, 3, 5]

Categories

Resources