to remove the last few components in list with python - python

a=[3,2,2,3]
a.sort()
a.pop(a[3])
print(a)
a.pop(a[2])
print(a)
I want to delete the last two element in list a after sorting, but I get this error:
[2, 2, 3]
Traceback (most recent call last):
File "E:/Project/8.py", line 5, in <module>
a.pop(a[2])
IndexError: pop index out of range

pop(i) pops the element at index i in the list. When you do a.pop(a[3]), you're popping the element at index a[3]=3. If you want to pop the last element, just do a.pop() without any argument, it will implicitly pop the last element.

The reason you're getting the error is because you're looking up what index to pop by retrieving an integer from the list, so by doing a[2], you are first fetching the value 3 and obviously this is outside of the range of the list.
So as said otherwise, just call pop without the parameter - pop()

Simply make the list equal to itself minus the last two elements.
a=[3,2,2,3]
a.sort()
a=a[:-2]

First of all pop is able to just remove the last element, you don't need to specify the argument.
Removing the sorting as it doesn't change much here you get:
a=[2,2,3,3]
a.pop()
print(a)
a.pop()
print(a)
It should do what you probably wanted.
More context and explanation
As explained in the docs if you optionally specify the parameter to pop - it takes in the index of the element to be removed.
So in yet even more simpler code:
a=[3,2,2,3]
a.pop(a[3])
What it means is:
a[3] - take third element of the list, it's 3 (remember this is 0-indexed)
so in this situation a.pop(a[3]) happens to be the same as a.pop(3)
so it removes the third element
Now your error happens because you do a.pop(a[2]) which is again a 3, and the list is too short.

Others have already pointed out your usage error.
Even easier, just take the slice of list that you want:
a = sorted(a)[:-2]
This sorts the list, strips off the last two entries, and assigns the result back to a.
>>> a = [5, 8, 3, 2]
>>> a = sorted(a)[:-2]
>>> a
[2, 3]

just use the pop function twice without parametrs like this:
a.pop()
a.pop()

If you want to remove the last elements you dont need to pass a parameter to pop. Just call a.pop() twice.
The problem rest in that you are not passing the index but the value of the array in the determinate position. When you do pop of a[3] the value is 3 and that index no longer exist because the array size is 3 and the last index is 2.

Related

Strange slicing behavior in Python

I found this to be a bit strange. Can anyone explain to me: Why, if I have a list like this:
l = [1, 2, 3, 4, 5]
and I do this reassignment:
l[-1:0] = [99,]
then it inserts the 99 to the left of the 5, like so:
[1, 2, 3, 4, 99, 5]
We must assign to an iterable [99,], assigning to just the integer 99 will give an error, which might be a clue as to what's happening here... I guess?
According to the official Docs:
In the table s is an instance of a mutable sequence type, t is any iterable object and x is an arbitrary object that meets any type and value restrictions imposed by s
Note (1): t must have the same length as the slice it is replacing.
So, if you do l[-1] = 99, you are replacing the item in position -1 (that means, one less than the last) to the value 99.
On the other hand, if you do l[-1:0] = [99,], you taking the elements from index -1 to 0 (that means, a slice of length zero in the position -1), and replacing those by the elements of [99,] (that is why it must be an iterable), which effectively is a semantic insert.
When you slice a Python list with [start:end] you end up with another list. The beginning of the new list in your example is the location of the last element in your original list. Just because the value of l[-1:0] in your example is [] it does not mean that this is simply an empty list. Its value is an empty list, but the reference to l[-1:0] is to a sliced list within an existing list.
So in your example
l = [1,2,3,4,5]
# ^ l[-1:0] starts here but the size is 0
When you assign a list to a sliced position of another list, you are effectively performing list concatenation.
This is the equivalent of what you are doing.
l=[1,2,3,4,5]
l[4:0] = [99] # concatenate a new list at the position of the final element in the original list
# A different way to look at it
l[0:4] + [99] + l[4:]
The result again is effectively concatenating the two lists. More specifically, you are inserting the elements of a new list into the original at the position you've indicated. Using a literal integer such as 99 will result in an error because you cannot concatenate an int and a list directly. However, as others have pointed out, a slice assignment can use any iterable, so l[-1,0] = (99,) works by the same principle.
First, you'll need to know how the slicing works fully. You can have 3 values:
[start:end:step]
In your code, l[-1:0], using -1 as the start value will aim at the last value in the list, but it'll also try and find a list of values because of the end value being set. This is why you had to use a list to change the value.
To solve this issue, use l[-1] = 99 to change the last value of the list to 99 (assuming that's the intended result)

I can't print a specific set in a list in python

coordinates=[(4,5),(5,6,(6,6))]
print(coordinates[3])
result:Traceback (most recent call last):
File "C:\Users\PycharmProjects\pythonProject1\App.py", line 2, in <module>
print(coordinates[3])
IndexError: list index out of range
I want the result to be [6,6] instead of the error message what do you mean i am trying to access a fourth one I am trying to access the 3rd one in the list when i use coordinates[1][2] it gives me a syntax error
You want to double check the way you formatted your list.
From the looks of it, your list has index 0 (4,5) and index 1 (5,6,(6,6)). Your list simply has nothing at index 3 because there are only 2 entries. That's what the error message means.
You might want to change your list into coordinates=[(4,5),5,6,(6,6)], then you have index 0-3.
Try this:
print(coordinates[1][-1])
or
print(coordinates[1][2])
There are 2 problems:
(1) Items in a list are zero-indexed, meaning the first element of L is L[0], second is L[1], etc. So if you want the third item:
print(coordinates[2])
(2) If you just stop there, you'll still get an index out of range exception, because your list has only 2 elements. I think you've misplaced a ):
coordinates=[(4,5),(5,6),(6,6)]
In your question, your list coordinates has 2 elements: (4, 5) and (5, 6, (6, 6)) - notice the nested parentheses. The second item is the set containing 3 elements: 5, 6, and another set (6,6).
Tip: Sometimes I like to put lists on multiple lines, especially if they are nested or contain sets/tuples/other complicated structures. One widely accepted style for this is shown below:
coordinates = [
(4,5),
(5,6),
(6,6),
]
EDIT: Thanks to Ignatius Reilly for catching my missing commas!
Note: you are allowed to have a comma after the last element, which I usually do. It makes it easier to add more elements or rearrange them later using copy/paste.

How can I pop elements in a list from a given array of indexes?

I have a list
list=[[5,7,8],[2,8,4],[1,72,7],[8,79,80],[4,39,84],[6,78,89],[80,78,81],[12,39,50]]
and I have a list for indexes:
indexes=[1,3,7]
In the end, I want to remove 1st, 3rd and 7th element from the list
and the output should be like:
[[5,7,8],[1,72,7],[4,39,84],[6,78,89],[80,78,81]]
I used this code:
for i in indexes:
list.pop(i)
but it does not work, how can I fix that?
I'd create a new list that doesn't include these indexes. Using a list comprehension over the enumerate of the original list (so you can get the list and the index easily) can even make this a one liner:
result = [e[1] for e in enumerate(lst) if e[0] not in indexes]
Assuming the problem is caused by the mutation of the list during items popping:
for i in sorted(indexes, reverse=True):
list.pop(i)
The change in the code pops the items from the end first, so the indices of the other items is not affected.
Your way of doing this won't work since you will mess up the original list indexes by working with a non-reversed list for the loop.
Given your values, you should sort the indexes list and reverse the order to not mess with the list index, I'm also using del to avoid useless returns from the pop method.
list=[ [5,7,8],[2,8,4],[1,72,7],[8,79,80],[4,39,84],[6,78,89],[80,78,81],[12,39,50] ]
indexes=[1,3,7]
for index in sorted(indexes, reverse=True):
del list[index]
list=[[5,7,8],[2,8,4],[1,72,7],[8,79,80],[4,39,84],[6,78,89],[80,78,81],[12,39,50]]
indexes=[1,3,7]
for i in indexes[::-1]:
list.pop(i)
print(list)
When you run this code you will get an error Showing IndexError: pop index out of range.
This error occurs because, in the for loop for the first iteration the 2nd element i.e list[1] is poped and length of the list i.e len(list) becomes to 6, in the same way in second iteration after poping the list. The length of the list becomes 5. But in the third iteration from indexes you are passing 7 as index to the pop function but the length of the list after 2nd iteration is 5, so your passing the index which is greater then the length of the list this leads to IndexError: pop index out of range
To over come this error you have to iterate the list indexes from right to left i.e in reverse order.
the code that you're looking for is this
my_list=[[5,7,8],[2,8,4],[1,72,7],[8,79,80],[4,39,84],[6,78,89],[80,78,81],[12,39,50]]
indexes=[1,3,7]
for i in indexes[::-1]:
my_list.pop(i)
print(my_list)
Rename the variable from "list" to something else since list is a reserved word. you'll also have to do this in the for loop.
because you want to pop items out of a list it's important you think about the order you do it in. So if you pop from position 1 then that means position 2 will now become position 1. this probably isn't what you want.
so it's important to pop from the end of the list first and work your way to the front if possible which is why I used the
indexes[::-1]
this is called list slicing you can learn more about it here.
https://www.youtube.com/watch?v=ajrtAuDg3yw

How do i 'replace' an array by filling an empty array's elements using pop method from another array?

I'm trying to implement a stack in python and I'm experimenting with the list data structure. If i want to use the pop method to 'fill' an empty array by using the elements from an existing array, what do I do?
# Implementing Stacks in Python through the given list structure
practiceStack = []
practiceStack.append(['HyunSoo', 'Shah'])
practiceStack.append('Jack')
practiceStack.append('Queen')
practiceStack.append(('Aces'))
# printing every element in the list/array
for i in practiceStack:
print(i)
# since stacks are LIFO (last in first out) or FILO (first in last out), the pop method will remove the first thing we did
emptyArrayPop = []
This is what I tried (by using a for loop) and keep getting a use integers not list error
for i in practiceStack:
emptyArrayPop[i].append(practiceStack.pop)
print(emptyArrayPop)
The pop function is a function — not a value. In other words, practiceStack.pop is a pointer to a function (you can mostly ignore this until you've spent more time around code); you likely want this instead:
practiceStack.pop()
You also need to append to the list; when adding something with append, the List will automatically add it at the end; you do not need to provide an index.
Further explanation: The List.append method will take the value that you pass to it and add that to the end of the List. For example:
A = [1, 2, 3]
A.append(4)
A is now [1, 2, 3, 4]. If you try to run the following:
A[2].append(4)
...then you are effectively saying, "append 4 to the end of the value at position-2 in A", (`A[2] is set to 3 in the above example; remember that python lists start counting at 0, or are "0-index".) which is like saying "Append 4 to 3." This makes no sense; it doesn't mean anything to append an integer to another integer.
Instead, you want to append to the LIST itself; you do not need to specify a position.
Don't get this confused with assigning a value to a position in a List; if you were setting a value at an existing position of a list, you can use the = operator:
>>> B = [1, 2, 3]
>>> B[2]
3
>>> B[2] = 4
>>> print(B)
[1, 2, 4]
>>> B.append(8)
>>> print(B)
[1, 2, 4, 8]
So to answer your original question, the line you want is the following:
emptyArrayPop.append(practiceStack.pop())
(note the [i] has been removed)
[edit] Not the only issue, as #selcuk pointed out.
You will also need to fix the way you're accessing data in the practiceStack list, as you cannot edit a list (calling pop modifies the list in-place) when you are iterating over it.
You will need to iterate over the integer index of the list in order to access the elements of practiceStack:
for i in range(len(practiceStack)):
emptyArrayPop.append(practiceStack.pop())

Python Pop Loop

Running into something which seems strange. I use a set of lists to hold some data and if a condition is met in them I want to remove that data from each list.
This is what I have currently. It works and removes everything from the first result but when there's more than one meeting the criteria it leaves them.
agecounter = 0
for matches in List1:
if Condition Met:
List1.pop(agecounter)
List2.pop(agecounter)
List3.pop(agecounter)
agecounter = agecounter + 1
If I have 10 items in those lists and three meet the criteria it'll remove the first one. I can even print the data from the other results meeting the condition. It prints it to the console just fine, doesn't throw an exception but seems to just ignore the pop.
I might be missing something really obvious here but there's no reason for that not to work, is there?
Traverse your list in reverse order
agecounter = len(List1)-1
for matches in reversed(List1):
if Condition Met:
List1.pop(agecounter)
List2.pop(agecounter)
List3.pop(agecounter)
agecounter = agecounter - 1
It's not a good idea to remove elements from a list while iterating over it. You should probably iterate over a copy of your list instead
A full example that shows the problem would help get better answers.
That being said, pop is probably not working as you expect. It's not removing agecounter from the list. It's removing the item at position agecounter.
>>> a = [1,2,3, 4]
>>> a.pop(1)
2
>>> a
[1, 3, 4]
>>> a.pop(2)
4
And when you get higher you're more likely to go off the end, throwing an exception.
>>> a.pop(3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: pop index out of range
Adding to #StephenTG's answer you probably want to copy the data rather than modify it during iteration. You can "filter" it using a list comprehension:
a = [1,2,3,4]
>>> b = [2,3]
>>> [x for x in a if x not in b]
[1, 4]

Categories