Split list after repeating elements - python

I have this loop for creating a list of coefficients:
for i in N:
p = 0
for k in range(i+1):
p += (x**k)/factorial(k)
c.append(p)
For example N = [2, 3, 4] would give list c:
[1.0, 2.0, 2.5, 1.0, 2.0, 2.5, 2.6666666666666665, 1.0, 2.0, 2.5, 2.6666666666666665, 2.708333333333333]
I want a way of making separate lists after each 1.0 element. For example a nested list:
[[1.0, 2.0, 2.5], [1.0, 2.0, 2.5, 2.6666666666666665], [1.0, 2.0, 2.5, 2.6666666666666665, 2.708333333333333]]
I was thinking of using an if test, like
for c_ in c:
if c_ == 1.0:
anotherList.append(c_)
This only appends 1.0's though and I don't know how I can make it append everything after a one instead of just 1.0.

you can use itertools.groupby in list comprehension :
>>> [[1.0]+list(g) for k,g in itertools.groupby(l,lambda x:x==1.0) if not k]
[[1.0, 2.0, 2.5], [1.0, 2.0, 2.5, 2.6666666666666665], [1.0, 2.0, 2.5, 2.6666666666666665, 2.708333333333333]]

Try something like
another_list = []
for c_ in c:
if c_ == 1.0:
another_list.append([])
another_list[-1].append(c_)
Thanks for the suggestion #James Jenkinson

Related

How to sum certain floats in a list

I wonder how to sum up only the floats in this list,
list = ['abc', 3.0, 2.0, 2.0, 0.0, 1.0, 0.0, 0.0]
I can't find out how to exclude the first string. I would like to do something with
range(1, len(list))
as it will need to work on lists with longer lengths, maybe something similar to it with the same effect? For python 3
You can use a generator in sum() and isinstance() to check if something is a float.
>>> lst = ['abc', 3.0, 2.0, 2.0, 0.0, 1.0, 0.0, 0.0]
>>> sum(x for x in lst if isinstance(x, float))
8.0
Note you should not use list as a variable name as it will overwrite the built in list class.
my_list = ['abc', 3.0, 2.0, 2.0, 0.0, 1.0, 0.0, 0.0]
sum = 0
for i in my_list:
if type(i) is float:
sum += i
print(sum)
This will result the sum to 8.0

How to find part of series in some series

The question is simple.
Suppose we have Series with this values:
srs = pd.Series([7.0, 2.0, 1.0, 2.0, 3.0, 5.0, 4.0])
How can I find place (index) of subseries 1.0, 2.0, 3.0?
Using a rolling window we can find the first occurrence of a list a.It puts a 'marker' (e.g. 0, any non-Nan value will be fine) at the end (right border) of the window. Then we use first_valid_index to find the index of this element and correct this value by the window size:
a = [1.0, 2.0, 3.0]
srs.rolling(len(a)).apply(lambda x: 0 if (x == a).all() else np.nan).first_valid_index()-len(a)+1
Output:
2
The simplest solution might be to use list comprehension:
a = srs.tolist() # [7.0, 2.0, 1.0, 2.0, 3.0, 5.0, 4.0]
b = [1.0, 2.0, 3.0]
[x for x in range(len(a)) if a[x:x+len(b)] == b]
# [2]
One naive way is to iterate over the series, subset the n elements and compare if they are equal to the given list:
Here the code:
srs = pd.Series([7.0, 2.0, 1.0, 2.0, 3.0, 5.0, 4.0])
sub_list = [1.0, 2.0, 3.0]
n = len(sub_list)
index_matching = []
for i in range(srs.shape[0] - n + 1):
sub_srs = srs.iloc[i: i+n]
if (sub_srs == sub_list).all():
index_matching.append(sub_srs.index)
print(index_matching)
# [RangeIndex(start=2, stop=5, step=1)]
Or in one line with list comprehension:
out = [srs.iloc[i:i+n].index for i in range(srs.shape[0] - n + 1) if (srs.iloc[i: i+n] == sub_list).all()]
print(out)
# [RangeIndex(start=2, stop=5, step=1)]
If you want an explicit list:
real_values = [[i for i in idx] for idx in out]
print(real_values)
# [[2, 3, 4]]

How to calculate and replace values in a list of lists

I have a list of lists with floating numbers.
lst = [[1.0,2.0,3.0] , [0.0,1.0,2.0] , [1.0,2.0,3.0]]
For each element, I want to find the reciprocal and ignore if == 0.0
No modules please, using lists and loops preferred.
This is all I've come up with:
lst = [[1.0,2.0,3.0] , [0.0,1.0,2.0] , [1.0,2.0,3.0]]
new_values=[]
for slist in lst:
for x in slist:
if x!=0.0:
reciprocal=1.0/x
new_values.append(reciprocal)
else:
reciprocal=0.0
new_values.append(reciprocal)
But of course, this just creates a new list, whereas I want it to stay within the list of lists I've written (lst).
Expected
lst=[[1/1.0, 1/2.0, 1/3.0] , [1/1.0, 1/2.0] , etc...]]
NOTE that the 0.0 I had initially in lst[1] is removed after the calculation.
Use a list comprehension and overwrite your lst variable:
lst = [[x if x == 0.0 else 1/x for x in l] for l in lst]
Note that x == 0.0 is bad practice but I gather that's not the point of this question
Output:
[[1.0, 0.5, 0.3333333333333333], [0.0, 1.0, 0.5], [1.0, 0.5, 0.3333333333333333]]
If you want to change the values in the nested list instead of replacing it with a new list you could do:
lst = [[1.0, 2.0, 3.0] , [0.0, 1.0, 2.0] , [1.0, 2.0, 3.0]]
for slist in lst:
for i, x in enumerate(slist):
slist[i] = 1.0 / x if x != 0.0 else 0.0
print(lst)
# [[1.0, 0.5, 0.3333333333333333], [0.0, 1.0, 0.5], [1.0, 0.5, 0.3333333333333333]]
lst = [[1.0,2.0,3.0] , [0.0,1.0,2.0] , [1.0,2.0,3.0]]
def reciprocate(list_input):
new_list = []
for x in list_input:
if x!=0.0:
new_list.append(1/x)
return new_list
new_lst = [reciprocate(l) for l in lst]
print(new_lst)
This gives the following output.
[[1.0, 0.5, 0.3333333333333333], [1.0, 0.5], [1.0, 0.5, 0.3333333333333333]]
You need to create a nested list in each of the outer iterations.
lst = [[1.0,2.0,3.0] , [0.0,1.0,2.0] , [1.0,2.0,3.0]]
new_values=[]
for slist in lst:
new_sublist = []
for x in slist:
if x!=0.0:
reciprocal=1.0/x
else:
reciprocal=0.0
new_sublist.append(reciprocal)
new_values.append(new_sublist)
You can use list comphrensions to achieve the needed:
lst = [[1.0,2.0,3.0] , [0.0,1.0,2.0] , [1.0,2.0,3.0]]
reciprocals = [list(map(lambda x: (1/x) if x != 0.0 else 0.0, sub_list)) for sub_list in lst]
Outputting:
[[1.0, 0.5, 0.3333333333333333], [0, 1.0, 0.5], [1.0, 0.5, 0.3333333333333333]]

how to conditionally replace values in list of lists in python

I am a python new bie.
I have two list of lists like this:
A = List[List[float,float]]
B = List[List[float,float]]
both different sizes
Ex :
A has [time, value]
B has [start_time, end_time]
A = [[0.0,10.0] , [1.0,10.0], [2.0,10.0], [3.0,10.0], [4.0,10.0], [5.0,10.0], [6.0,10.0]]
B = [[0.0,2.0], [5.0,6.0]]
What I am trying to do is :
if A has a time which is not in B, I should make the corresponding 'value' in A to zero.
So output would be :
[[0.0,10.0] , [1.0,10.0], [2.0,10.0], [3.0,0.0], [4.0,0.0], [5.0,10.0], [6.0,10.0]]
i.e if a time segment in B has no corresponding time value present in A, the value corresponding to that time should be made zero. In this case, the values between 2 and 5 are there in B , so partner values of'3' and '4' in A are made to zeroes.
Please tell me how to do it.
I have referred here: Python - How to change values in a list of lists? and List of lists into numpy array
So One idea i got was to convert B into single list and then compare values from AA and A. However I haven't made much progress.
AA = numpy.hstack(B) # for getting array of times
for i in 1: len(AA):
if (AA[i]==A[
For simple problems, a nested loop design can often get you to a quick solution without needing to worry about the specifics of list-flattening functions.
for i in range(len(A)):
time = A[i][0]
isValidTime = False
for time_segment in B:
if time_segment[0] <= time <= time_segment[1]:
isValidTime = True
break
if not isValidTime:
A[i][1] = 0.0
Edit: Just to be clear, including the 'break' statement isn't necessary to get to the solution, but it helps avoid unnecessary computation. If we've determined that an item in A does have a valid time, we can safely stop searching through the time segments in B and move on to the next item of A.
If you flatten B, then you can compare it:
A = [[0.0, 10.0], [1.0, 10.0], [2.0, 10.0], [3.0, 10.0], [4.0, 10.0], [5.0, 10.0], [6.0, 10.0]]
B = [[0.0, 2.0], [5.0, 6.0]]
Bvals = [item for sublist in B for item in sublist]
print(Bvals)
newA = [x if x[0] in Bvals else [x[0], 0.0] for x in A]
print(newA)
Outputs:
[0.0, 2.0, 5.0, 6.0]
[[0.0, 10.0], [1.0, 0.0], [2.0, 10.0], [3.0, 0.0], [4.0, 0.0], [5.0, 10.0], [6.0, 10.0]]
I suppose the B list contains time intervals, right? In that case, you can do something like the following:
updated = [x if any([start <= x[0] end <= for start, end in B]) else [x[0], 0] for x in A]
That may be a bit too compact for some people, but it essentially does the same as the following:
updated = []
for time, value in A:
for start, end in B:
if start <= time and time <= end:
updated.append([time, value])
break
updated.append([time, 0])
On a side note, if you are doing interval checking, this is probably not the most efficient way to do it. Take a look at interval trees, which is a data structure for performing various interval-related queries (yours included).
A Pythonic one-liner:
[[t,v if any(s <= t and t <= e for s,e in B) else 0.0] for t,v in A]
which gives:
[[0.0, 10.0], [1.0, 10.0], [2.0, 10.0], [3.0, 0.0], [4.0, 0.0], [5.0, 10.0], [6.0, 10.0]]

Equating the lengths of the arrays in an array of arrays

Given an array of arrays with different lengths. Is there a cleaner (shorter) way to equate the lengths of the arrays by filling the shorter ones with zeros other than the following code:
a = [[1.0, 2.0, 3.0, 4.0],[2.0, 3.0, 1.0],[5.0, 5.0, 5.0, 5.0],[1.0, 1.0]]
max =0
for x in a:
if len(x) > max:
max = len(x)
print max
new = []
for x in a:
if len(x)<max:
x.extend([0.0]* (max-len(x)) )
new.append(x)
print new
You can find the length of the largest list within a using either:
len(max(a, key=len))
or
max(map(len, a))
and also use a list comprehension to construct a new list:
>>> a = [[1.0, 2.0, 3.0, 4.0], [2.0, 3.0, 1.0], [5.0, 5.0, 5.0, 5.0], [1.0, 1.0]]
>>> m = len(max(a, key=len))
>>> new = [x + [0]*(m - len(x)) for x in a]
>>> new
[[1.0, 2.0, 3.0, 4.0], [2.0, 3.0, 1.0, 0], [5.0, 5.0, 5.0, 5.0], [1.0, 1.0, 0, 0]]
In: b = [i+[0.]*(max(map(len,a))-len(i)) for i in a]
In: b
Out:
[[1.0, 2.0, 3.0, 4.0],
[2.0, 3.0, 1.0, 0.0],
[5.0, 5.0, 5.0, 5.0],
[1.0, 1.0, 0.0, 0.0]]

Categories

Resources