Python - Splitting lists of integers during iteration - python

I have an array of data where I'm taking a slice through a 3D array of floats and appending the numbers of the elements that satisfy a set of upper and lower bounds (also floats).
The first part of my code contains a nested for loop in the style of the following:
x_lst = []
for i in range(len(x1)):
for x in range(len(floatarray[0,:,0])):
if x1[i] <= floatarray[0,x,0] <= x2[i]:
x_lst.append(x)
#issues after this point
The inner loop compares the data in the array (floatarray[0,x,0]) with the boundaries x1 and x2, returning a list of integers, whilst the outer loop iterates through the values of the boundaries.
The issue I have is that the output (x_lst) is a single list, whereas I've been trying to produce a list of lists, with each sublist corresponding to the iterable i.
e.g.
#Desired output
x_lst = [[5,6,7,13,14],[21,22,23,36,37],[44,45,...
#Actual output
x_lst = [5,6,7,13,14,21,22,23,36,37,44,45,...
I feel like there's a very simple way of doing this, but I've not been able come up with anything that works (such as trying to use x_lst.split() after the append).
Also, any feedback on the question would be great as I'm still fairly new to SO.

It seems the following should work: why not create an intermediate sublist for each i, and add appropriate values to the sublist, then finally add the sublist to the main list?
x_lst = []
for i in range(len(x1)):
inner_list = [] # The sublist to be appended.
for x in range(len(floatarray[0,:,0])):
if x1[i] <= floatarray[0,x,0] <= x2[i]:
inner_list.append(x) # Add the numbers to the sublist.
# Issues after this point...
x_lst.append(inner_list) # Add the sublist to the main list.

Everything appears to be correct in the code except that you append into a 1-d array. For solving your problem you can simply change your code so that a temporary array named temp will append data in inner loop which would then be appended to your outer array x_lst as shown below:
x_lst = []
for i in range(len(x1))
temp=[]
for x in range(len(floatarray[0,:,0])):
if x1[i] <= floatarray[0,x,0] <= x2[i]:
temp.append(x)
x_lst.append(temp);

Okay, so Sam's answer is correct insofar as appending the values through the iteration, but trying it out with my code produced lists of lists of len(i) where each sublist contained all values of x that satisfied all elements of x1 and x2, instead of each list containing values specific to the [i]th element of x1 and x2, thus all the sublists were identical.
I got around this by replacing the inner for loop with a list comprehension, as follows, that gave the right result (in the desired form x_lst = [[5,6,7,13,14],[21,22,23,36,37],[44,45,...):
x_lst = []
for i in range(len(x1)):
y = [x for x in range(len(floatarray[0,:,0])) if x1[i] <= floatarray[0,x,0] <= x2[i]]
x_lst.append(y)

Related

Taking n elements at a time from 1d list and add them to 2d list

I have a list making up data, and I'd like to take 4 elements at a time from this list and put them in a 2d list where each 4-element increment is a new row of said list.
My first attempts involve input to 1d list:
list.append(input("Enter data type 1:")) list.append(input("Enter data type 2:")) etc.
and then I've tried to loop the list and to "switch" rows once the index reaches 4.
for x in range(n * 4):
for idx, y in enumerate(list):
if idx % 4 == 0:
x = x + 1
list[y] = result[x][y]
where I've initialised result according to the following:
and
ran = int(len(list)/4)
result=[[0 for x in range(ran)] for j in range(n)]
I've also attempted to ascribe a temporary empty list that will append to an initialised 2D list.
`
row.append(list)
result=[[x for x in row] for j in range(n + 1)]
#result[n]=row
print(result)
n = n + 1
row.clear()
list.clear()
so that each new loop starts with an empty row, takes input from user and copies it.
I'm at a loss for how to make result save the first entry and not be redefined at second,third,fourth entries.
I think this post is probably what you need. With np.reshape() you can just have your list filled with all the values you need and do the reshaping after in a single step.

Excluding values in array - python

Ok so I have an array in python. This array holds indices to another array. I removed the indices I wanted to keep from this array.
stations = [1,2,3]
Let's call x the main array. It has 5 columns and I removed the 1st and 5th and put the rest in the array called stations.
I want to be able to create an if statement where the values from stations are excluded. So I'm just trying to find the number of instances (days) where the indices in the stations array are 0 and the other indices (0 and 4) are not 0.
How do I go about doing that? I have this so far, but it doesn't seem to be correct.
for j in range(len(x)):
if x[j,0] != 0 and x[j,4] != 0 and numpy.where(x[j,stations[0]:stations[len(stations)-1]]) == 0:
days += 1
return days
I don't think your problem statement is very clear, but if you want the x cols such that you exclude the indices contained in stations then do this.
excluded_station_x = [col for i, col in enumerate(x) if i not in stations]
This is a list comprehension, its a way for building a new list via transversing an iterable. Its the same as writing
excluded_station_x = []
for i, col in enumerate(x):
if i not in stations:
excluded_station_x.append(col)
enumerate() yields both the value and index of each element as we iterate through the list.
As requested, I will do it without enumerate.
You could also just del each of the bad indices, although I dislike this because it mutates the original list.
for i in stations:
del x[i]

Adding a list to itself after addition to each value

I have a list of integers that follows a particular pattern, it's complex but for example say:
x = [0,2,4,6,8]
I'd like to extend the list with 9 more copies of itself, but add a constant value that linearly scales each time. E.g. if
constant = 10
loop = 9
Then the 2nd extension would result in:
x_new = [0,2,4,6,8,10,12,14,16,18]
So I think I want a loop that iterates through x and extends the array by x[i]+constant, loop number of times?
for i in range(loop):
for j in range(len(x)):
x_new = x.extend((x[j]+constant)*i)
Or perhaps this can be easily done through list comprehension? My actual list is ~3000 long and I'll be doing it a few times with different values of loop and constant.
Yes, list comprehension should work:
x_new = [ e + constant * i for i in range(loop+1) for e in x ]
I just did some work on above question, this code can be useful for above question.
x=[0,2,4,6,8]
y=x[4]
i=0
j=0
while(i<9):
z=range(y+2,y+12,2)
x.extend(z)
print x
y=y+10
i=i+1

why is it giving index error out of range although i am almost sure I am in range?

i was trying to fill a list with inputs, but it gave me index out of range
although the index is starting from zero, as far as i know we don't have to specify the length of a list in python.
inputs = input("Enter the number of inputs: ")
lists = []
k = 0
while k<inputs:
lists[k]= input()
k+=1
Because you are creating an empty list with lists = [] and then accessing an element of this empty list. This is the cause of the IndexError.
Appending with lists.append() helps you avoid index errors like this one. You generally want to use indexing when accessing elements and not when populating the list.
You can initialize your list before using indexes of it:
lists = [0] * int(inputs)
And then you can use your code
Use list.append() to add an element to the end of the list:
while k<inputs:
lists.append(input())
k+=1
or with a list comprehension:
lists = [input() for _ in range(inputs)]
Another possibility: Initialize lists as an empty list and then append the input with the += operand.
lists = []
k = 0
while k < inputs:
lists += [input()]
k+=1

How is this 2D array being sized by FOR loops?

Question background:
This is the first piece of Python code I've looked at and as such I'm assuming that my thread title is correct in explaining what this code is actually trying to achieve i.e setting a 2D array.
The code:
The code I'm looking at sets the size of a 2D array based on two for loops:
n = len(sentences)
values = [[0 for x in xrange(n)] for x in xrange(n)]
for i in range(0, n):
for j in range(0, n):
values[i][j] = self.sentences_intersection(sentences[i], sentences[j])
I could understand it if each side of the array was set with using the length property of the sentences variable, unless this is in effect what xrange is doing by using the loop size based on the length?
Any helping with explaing how the array is being set would be great.
This code is actually a bit redundant.
Firstly you need to realize that values is not an array, it is a list. A list is a dynamically sized one-dimensional structure.
The second line of the code uses a nested list comprehension to create one list of size n, each element of which is itself a list consisting of n zeros.
The second loop goes through this list of lists, and sets each element according to whatever sentences_intersection does.
The reason this is redundant is because lists don't need to be pre-allocated. Rather than doing two separate iterations, really the author should just be building up the lists with the correct values, then appending them.
This would be better:
n = len(sentences)
values = []
for i in range(0, n):
inner = []
for j in range(0, n):
inner.append(self.sentences_intersection(sentences[i], sentences[j]))
values.append(inner)
but you could actually do the whole thing in the list comprehension if you wanted:
values = [[self.sentences_intersection(sentences[i], sentences[j]) for i in xrange(n)] for j in xrange(n)]

Categories