python slicing [:-N] [:-N+1] - python

I been trying to code the following line but I get the message that operands could not be broadcast together with shapes (0,) (30,)
x has a length of 32
x[:-N+1] I want to access all elements except the last two
x[N:-N] I want to access all elements except the first one and the last one
x[N+1:] I want to access all elements except the first
y = x[:-N+1] - 2 * x[N:-N] + x[N+1:]
How should I index x to access those values? I'm new to python so any tips would be appreciated.

Slice except the last two: x[:N-2]
Except first and last: x[1:N-1]
Except first two: x[2:]
Python slice can be obtained by:
x[starting_index:end_index] {including starting_index element and excluding end_index}
If you don't specify the starting_index, it becomes 0 by default.
If you don't specify the end_index, it becomes N by default.

Considering the list length might be vary, the python has good apporach to access the items of a list.
Given a alist=['a','b','something',1,2]
if you use alist[1:], you will get ['b', 'something', 1, 2]
if you use alist[:1], you will get ['a','b','something',1]
if you only use alist[1], you will only get a ,which is the first item of the list.
so, if you use alist[-1:], you will get 2 , which is the first item starts from right.
if you use alist[:-1], you will get ['a','b','something',1] , which are items start from right except the fist.
In conclusion, the empty thing in the [:] is what you will get after use slicing.

Related

Enumerate - Python loop

I have two lists with just one element as follows(each of these two lists always contains only one element):
Vnew = [600]
Newoints2 = [(2447,3480)]
I'm trying to bring both of them together using the following code sample:
for i, key in enumerate(Vnew2):
pos3[key] = newpoints2[i]
But this returns an error as IndexError: list assignment index out of range
I actually did this one for other lists which have more than one element. It worked fine and got the output as {0:(1245,674),1:(2457,895),...}
Can someone find the mistake here?
It looks like you are trying to concatenate the lists into a new list. You don't always need to enumerate through the list.
You will be able to do this by Vnew + Newoints2

IndexError: list index out of range in python for strings [duplicate]

This question already has answers here:
How to remove items from a list while iterating?
(25 answers)
Closed 7 months ago.
I wanted to remove the word "hello" from this array, but I get the "index out of bounds" error. I checked the range of len(token); it was (0,5).
Here is the code:
token=['hi','hello','how','are','you']
stop='hello'
for i in range(len(token)):
if(token[i]==stop):
del(token[i])
You're getting an index out of bounds exception because you are deleting an item from an array you're iterating over.
After you delete that item, len(token) is 4, but your for loop is iterating 5 times (5 being returned from the initial len(token)).
There are two ways to solve this. The better way would be to simply call
token.remove(stop)
This way won't require iterating over the list, and will automatically remove the first item in the array with the value of stop.
From the documentation:
list.remove(x): Remove the first item from the list whose value is x. It is an error if there is no such item.
Given this information, you may want to check if the list contains the target element first to avoid throwing a ValueError:
if stop in token:
token.remove(stop)
If the element can exist multiple times in the list, utilizing a while loop will remove all instances of it:
while stop in token:
token.remove(stop)
If you need to iterate over the array for some reason, the other way would be to add a break after del(token[i]), like this:
for i in range(len(token)):
if(token[i]==stop):
del(token[i])
break
It's not recommended to delete a list element when iterating over this list. I'm not sure what you intend but you could create a new list without the stop
token=['hi','hello','how','are','you']
stop='hello'
new_tokens = []
for i in range(len(token)):
if(token[i]!=stop):
new_tokens.append(token[i])
or create a list with everything until stop is reached:
token=['hi','hello','how','are','you']
stop='hello'
new_tokens = []
for i in range(len(token)):
if(token[i]!=stop):
new_tokens.append(token[i])
else:
break
But never delete elements from a list you are iterating over because then the length of the list is modified but the range is not.
The reason you are getting this error is two fold:
you are using the anti pattern in Python of range(len(sequence)). You should use for index, value in enumerate(sequence)
You are mutating a sequence as you iterate across it.
The call to range(len(...)) is only evaluated once. So when you star it evaluates to 5. Once you remove your stop word the list no longer has 5 elements so token[4] results in an IndexError
Once you delete an item, there are no longer as many items in the list as there were originally, so i will get too big. Also, if you delete the item at index i, then the element that used to be at i+1 will now be at index i, but your code won't check it, since it goes ahead and increments i.
Use break statement after deleting because you are modifying the same list in which you are iterating.
for i in range(len(token)):
if(token[i]==stop):
del(token[i])
break
I don't disagree with any of the other answers, but the most Pythonic solution is to get rid of the loop entirely and replace it with one line:
token.remove(stop)
That will remove the first occurrence of 'hello' from the list.

Find index of a sublist in a list

Trying to find the index of a sublists with an element. I’m not sure how to specify the problem exactly (which may be why I’ve overlooked it in a manual), however my problem is thus:
list1 = [[1,2],[3,4],[7,8,9]]
I want to find the first sub-list in list1 where 7 appears (in this case the index is 2, but lll could be very very long). (It will be the case that each number will appear in only 1 sub-list – or not at all. Also these are lists of integers only)
I.e. a function like
spam = My_find(list1, 7)
would give spam = 2
I could try looping to make a Boolean index
[7 in x for x in lll]
and then .index to find the 'true' - (as per Most efficient way to get indexposition of a sublist in a nested list)
However surely having to build a new boolean list is really inefficient..
My code starts with list1 being relatively small, however it keeps building up (eventually there will be 1 million numbers arranged in approx. 5000 sub-lists of list1
Any thoughts?
I could try looping to make a Boolean index
[7 in x for x in lll]
and then .index to find the 'true' … However surely having to build a new boolean list is really inefficient
You're pretty close here.
First, to avoid building the list, use a generator expression instead of a list comprehension, by just replacing the [] with ().
sevens = (7 in x for x in lll)
But how do you do the equivalent of .index when you have an arbitrary iterable, instead of a list? You can use enumerate to associate each value with its index, then just filter out the non-sevens with filter or dropwhile or another generator expression, then next will give you the index and value of the first True.
For example:
indexed_sevens = enumerate(sevens)
seven_indexes = (index for index, value in indexed_sevens if value)
first_seven_index = next(seven_indexes)
You can of course collapse all of this into one big expression if you want.
And, if you think about it, you don't really need that initial expression at all; you can do that within the later filtering step:
first_seven_index = next(index for index, value in enumerate(lll) if 7 in value)
Of course this will raise a StopIteration exception instead of a ValueError expression if there are no sevens, but otherwise, it does the same thing as your original code, but without building the list, and without continuing to test values after the first match.

Having adding to dictionary problems python

This is part of my code:
add_values=[2,5,10,20,50,100,200,500,1000,2000,5000,10000,20000,50000]
for each in add_values:
print(each)
s=add_values[each]
s=int(s)
h=s*100
mydict[add_values[each]]=s
And it is bringing up this error:
IndexError: list index out of range
(For the s=add_values[each] line)
Please can you tell what is wrong here and what needs changing,
Thanks.
Think about reaching the fifth item in add_values:
for each in add_values:
print(each) # each == 50
s=add_values[each] # what's the fiftieth item in 'add_values'?!
You don't need to index into add_values, you are already accessing the value - replace add_values[each] with, simply, each.
each is the value, you can't use it as an index (mainly because the size of add_values is 14 and you have values that are greater than this inside add_values):
add_values=[2,5,10,20,50,100,200,500,1000,2000,5000,10000,20000,50000]
for each in add_values:
print(each)
s=each
s=int(s)
h=s*100
mydict[each]=s
Another solution would be to use an index:
add_values=[2,5,10,20,50,100,200,500,1000,2000,5000,10000,20000,50000]
for i in range(len(add_values)):
print(add_values[i])
s=add_values[i]
s=int(s)
h=s*100
mydict[add_values[i]]=s
You are using an array element as an array index, which is why you are getting an out-of-bounds error.
With Python's for loop notation, you don't need to access an index explicitly; just access the element, which in your case is each:
for each in add_values:
print(each)
s=each # kind of redundant, but this should work
for each in add_value sets each to 2, 5, 10, 20, 50, etc. On the 4th iteration of the loop, each is 20. When you say add_values[each], you get an error because add_values has only 14 elements and you're trying to access element number 20. You'd get in even more trouble if it tried to access element number 50000.

Python error: IndexError: list assignment index out of range

a=[]
a.append(3)
a.append(7)
for j in range(2,23480):
a[j]=a[j-2]+(j+2)*(j+3)/2
When I write this code, it gives an error like this:
Traceback (most recent call last):
File "C:/Python26/tcount2.py", line 6, in <module>
a[j]=a[j-2]+(j+2)*(j+3)/2
IndexError: list assignment index out of range
May I know why and how to debug it?
Change this line of code:
a[j]=a[j-2]+(j+2)*(j+3)/2
to this:
a.append(a[j-2] + (j+2)*(j+3)/2)
You're adding new elements, elements that do not exist yet. Hence you need to use append: since the items do not exist yet, you cannot reference them by index. Overview of operations on mutable sequence types.
for j in range(2, 23480):
a.append(a[j - 2] + (j + 2) * (j + 3) / 2)
The reason for the error is that you're trying, as the error message says, to access a portion of the list that is currently out of range.
For instance, assume you're creating a list of 10 people, and you try to specify who the 11th person on that list is going to be. On your paper-pad, it might be easy to just make room for another person, but runtime objects, like the list in python, isn't that forgiving.
Your list starts out empty because of this:
a = []
then you add 2 elements to it, with this code:
a.append(3)
a.append(7)
this makes the size of the list just big enough to hold 2 elements, the two you added, which has an index of 0 and 1 (python lists are 0-based).
In your code, further down, you then specify the contents of element j which starts at 2, and your code blows up immediately because you're trying to say "for a list of 2 elements, please store the following value as the 3rd element".
Again, lists like the one in Python usually aren't that forgiving.
Instead, you're going to have to do one of two things:
In some cases, you want to store into an existing element, or add a new element, depending on whether the index you specify is available or not
In other cases, you always want to add a new element
In your case, you want to do nbr. 2, which means you want to rewrite this line of code:
a[j]=a[j-2]+(j+2)*(j+3)/2
to this:
a.append(a[j-2]+(j+2)*(j+3)/2)
This will append a new element to the end of the list, which is OK, instead of trying to assign a new value to element N+1, where N is the current length of the list, which isn't OK.
At j=2 you're trying to assign to a[2], which doesn't exist yet. You probably want to use append instead.
If you want to debug it, just change your code to print out the current index as you go:
a=[]
a.append(3)
a.append(7)
for j in range(2,23480):
print j # <-- this line
a[j]=a[j-2]+(j+2)*(j+3)/2
But you'll probably find that it errors out the second you access a[2] or higher; you've only added two values, but you're trying to access the 3rd and onward.
Try replacing your list ([]) with a dictionary ({}); that way, you can assign to whatever numbers you like -- or, if you really want a list, initialize it with 23479 items ([0] * 23479).
Python lists must be pre-initialzed. You need to do a = [0]*23480
Or you can append if you are adding one at a time. I think it would probably be faster to preallocate the array.
Python does not dynamically increase the size of an array when you assign to an element. You have to use a.append(element) to add an element onto the end, or a.insert(i, element) to insert the element at the position before i.

Categories

Resources