while loop - IndexError: list index out of range - python

Maybe it's too simple and I just didn't see my mistake.
while list_a[y] in list_a != list_a[-1]:
print(y);y=y+1
returns IndexError: list index out of range
list_a looks like:
['00001', '00001', '00002', '00009', '0000G', '0000K', '0000K', '0000U', '0000U', '00013', '0001B', '0001D', '0001D', '0001L', '0001L', '0001N', '0001Q', '0001Q', '0001R', '0001U']
and my aim in the end is to delete some items from the list while iterating (that's why I want to use a while loop instead of for y in range(len(list_a))).

Think what you were trying for was:
while list_a[y] != list_a[-1]:
...
i.e. "while we're looking at the item that isn't equal to the last in the list". However, there will still be issues; what if items appear elsewhere in the list that are equal to the last item?
The general way to do this is to use a list comprehension to build a new list from the appropriate items in the old list:
list_b = [item for item in list_a if some_test(item)]

Related

I want to remove duplicates from the list using for loop.I am getting index out of bound error here:if lst[i]==lst[j]:

I have declared a list and sorted it.While iterating the second for loop I am getting :index out
of range error.
lst=[]
for i in range(5):
a=int(input())
lst.append(a)
lst.sort()
print(lst)
for i in range(0,len(lst)):
j=i+1
for j in range(len(lst)):
if lst[i]==lst[j]:
print("hii")
lst.pop(j)
print(lst)
As you remove elements from lst it's length change so your iteration breaks when it tries to access an empty index: "Index out of bound"
If you want to keep your structure you could catch that and exit the loop using a try/catch on IndexError but it's really ugly.
A more pythonic solution is to simply cast your list as a set then back to list. This works because sets remove all of their duplicate elements:
>>> list(set([1, 1, 2, 2, 3, 4,]))
[1, 2, 3, 4]
You shouldn't change the length of your list while iterating over it, I am assuming you want to delete all duplicates in your original list. You can use cast the list to a set with
set(lst)
before you sort or after you sort.
You're getting this error thrown as you are changing the length of a list whist iterating over it.
A simpler approach to removing all duplicates from a list would be to create a set based on the list which is then converted back to a list - this should be done before you sort your list as a set (by definition) does not preserve ordering of elements.
Using your example:
lst = []
for i in range(5):
a=int(input())
lst.append(a)
lst = list(set(lst)) # Remove duplicates from list
lst.sort() # Sort list

How do I check one index of list_a against every element in list_b, and repeat this process for all elements in list_a?

I am trying to iterate through list_a so that each index in list_a is checked against every index in list_b. I have read about how to check lists against each other by index, but so far only understand how to iterate through the lists at the same time.
for i in range(list_a)
if list_a[i] == list_b[i]
I considered using a while loop to use a single value of list_a and iterate through list_b
while i < len(list_b)
for list_a[0] == list_b[i]
for list_a[1] == list_b[i]
But if i write it like this then the index for a is manually determined and if it changes because the list it appended, which it needs to be elsewhere in my code, it will stop working. How can i use two separate counters so that i check each element of list_a against every element of list_b for every element of list_a. Could I use a counter?
The reason I want to write the code like this is to make sure I identify repeating elements in list_b and know every every location at which they exist.
If you want to check every element of list_a against every element in list_b you should use nested for
for el_a in list_a:
for el_b in list_b:
if el_a == el_b:
# do stuff

Python checking if string in list to list

I am having a hard time trying to understand how the "for" function works.
I want to make a script that only outputs the strings in list2 that are not inside list1. For example:
list1 = ["link1.com", "link2.com", "link3.com"]
list2 = ["link2.com", "link123.com"]
for list2 in list1:
print(list2)
{My intention was that the code printed:
link123.com
But instead it printed the strings from list1}
I can't get it to work. Help would be much appreciated. I am using python 3 by the way.
Use Set for this .
set(list2)-set(list1)
Check with python set
The loop for list2 in list1 is actually an assignment: in each iteration the variable list2 gets the value of the next item in list1 - that is why only the elements of list1 are printed.
You could iterate over the elements of list2 and print, if they are not in list1:
for element in list2:
if element not in list1:
print(element)
Or if you want to use a for loop (note that this isn't very efficient for large lists):
for string in list2:
if not string in list1:
print (string)
For loops
For loops allow you to repeat a piece of code multiple times. You could easily just write a conditional and a print statement multiple times for each item in the list. A for loops allows you to write that piece of code once and have it repeated for each item in the list.
You can iterate over item in list2 by doing the following
for item in list2:
print(item)
item is an arbitrary variable name that holds the value of the current item we are on, what follows in is the list that we want to iterate over. print(item) is the piece of code we want to repeat for each element in the list.
What this does is goes through every item in list2 and prints them but that is not what we want. We want to check to make sure that item is not in list1. This can be achieved through a conditional statement.
if item not in list1:
print(item)
Now we can join the two piece of code together.
for item in list2:
if item not in list1:
print(item)
Sets
Are a collection of items in no order where every item is unique. These sets are the same ones we encounter in mathematics, therefore we can perform mathematical set operations on them.
To go from a list of items to a set we use sList1 = set(list1) sList1 is now of type set and stores the elements in list1. The same can be done for list2.
Now that we have sList1 and sList2 we want to eliminate any duplicates in the two for that we can take the difference of sList1 and sList2 and print them out as follows print(sList2-sList1).
We can do all of this in one step.
print( set(list2) - set(list1) )
The semantic, that python will check if these items are in list1 is NOT part of the for-each-loop.
The 'set' - solution is maybe too advanced for you.
So straightforward you would:
for item in list2:
if item not in list1:
print(item)

Searching for substring in element in a list an deleting the element

I have a list and I am trying to delete the elements that have 'pie' in them. This is what I've done:
['applepie','orangepie', 'turkeycake']
for i in range(len(list)):
if "pie" in list[i]:
del list[i]
I keep getting list index out of range, but when I change the del to a print statement it prints out the elements fine.
Instead of removing an item from the list you're iterating over, try creating a new list with Python's nice list comprehension syntax:
foods = ['applepie','orangepie', 'turkeycake']
pieless_foods = [f for f in foods if 'pie' not in f]
Deleting an element during iteration, changes the size, causing IndexError.
You can rewrite your code as (using List Comprehension)
L = [e for e in L if "pie" not in e]
Something like:
stuff = ['applepie','orangepie', 'turkeycake']
stuff = [item for item in stuff if not item.endswith('pie')]
Modifying an object that you're iterating over should be considered a no-go.
The reason to why you get a error is because you change the length of the list when you delete something!
Example:
first loop: i = 0, length of list will become 1 less because you delete "applepie" (length is now 2)
second loop: i = 1, length of list will now become just 1 because we delete "orangepie"
last/third loop: i = 2, Now you should see the problem, since i = 2 and the length of the list is only 1 (to clarify only list[0] have something in it!).
So rather use something like:
for item in in list:
if "pie" not in item:
new list.append(item)
Another but longer way would be to note down the indexes where you encounter pie and delete those elements after the first for loop

Removing items from a list in a loop [duplicate]

This question already has answers here:
Strange result when removing item from a list while iterating over it
(8 answers)
Closed 7 years ago.
For quite a bit of time now I have been trying to figure out a way to loop through a list and remove the current item that I'm at. I can't seem to get this working as I would like it to. It loops just 1 time through, but I wanted it to loop 2 times. When I remove the removal line - it loops 2 times.
a = [0, 1]
for i in a:
z = a
print z.remove(i)
The output:
[1]
The output that I was expecting:
[1]
[0]
You're changing the list while iterating over it -- z = a doesn't make a copy, it just points z at the same place a points.
Try
for i in a[:]: # slicing a list makes a copy
print i # remove doesn't return the item so print it here
a.remove(i) # remove the item from the original list
or
while a: # while the list is not empty
print a.pop(0) # remove the first item from the list
If you don't need an explicit loop, you can remove items that match a condition with a list comprehension:
a = [i for i in a if i] # remove all items that evaluate to false
a = [i for i in a if condition(i)] # remove items where the condition is False
It is bad practice modify a list while you're looping through it†. Create a copy of the list:
oldlist = ['a', 'b', 'spam', 'c']
newlist = [x for x in oldlist if x != 'spam']
To modify the original list, write the copy back in-place with a slice assignment:
oldlist[:] = [x for x in oldlist if x != 'spam']
† For a gist of why this might be bad practice, consider the implementation details of what goes on with the iterator over the sequence when the sequence changes during iteration. If you've removed the current item, should the iterator point to the next item in the original list or to the next item in the modified list? What if your decision procedure instead removes the previous (or next) item to the current?
The problem is that you're modifying a with remove so the loop exits because the index is now past the end of it.
Don't try to remove multiple items of a list while looping the list. I think it's a general rule you should follow not only in python but also in other programming languages as well.
You could add the item to be removed into a separate list. And then remove all objects in that new list from the original list.

Categories