This question already has answers here:
How to remove items from a list while iterating?
(25 answers)
Closed 4 years ago.
I am having the list like below
list1=['abc','oops','#exclude=10','exclude=java* kln*','smith','johns']
I am trying to delete the element which contains the word 'exclude' by using the below code.
x=0
for i in list1:
if 'exclude' in i:
list1.pop(x)
x+=1
print list1
When I run the program, it is removing the first exclude not the second one. Please let me know how to remove all exclude and what is the mistake I am doing?
Here's a simple solution:
import re
list1=['abc','oops','#exclude=10','exclude=java* kln*','smith','johns']
regex = re.compile('.*exclude.*')
okay_items = [x for x in list1 if not regex.match(x)]
print(okay_items)
In your solution, you have used pop() and as per the documentation,
list.pop([i]):
Remove the item at the given position in the list, and return it. If
no index is specified, a.pop() removes and returns the last item in
the list.
The reason you are experiencing this kind of behavior is that you are mutating list1 as you are iterating over it. At the point when you pop #exclude=10
from list1, x == 2 and once the element is popped
list1 == ['abc','oops','exclude=java* kln*','smith','johns']
Now x increments to 3, but list1[3]==smith after popping, whereas you were expecting it to be exclude=java* kln* as in your original version of list1.
Since while deleting first element list shifting it's element that's why this is happening.
You can try this:-
list1=['abc','oops','#exclude=10','exclude=java* kln*','smith','johns']
new_ls = [list1.index(x) for x in list1 if 'exclude' in x]
for i in reversed(new_ls):
list1.pop(i)
print(list1)
The method pop() removes and returns last object or obj from the list.
Instead you can create a new list which does not include strings with "exclude" like this.
list1=['abc','oops','#exclude=10','exclude=java* kln*','smith','johns']
listWithoutExclude = []
for each in list1:
if "exclude" not in each:
listWithoutExclude.append(each)
print listWithoutExclude
try this,
>>> list1=['abc','oops','#exclude=10','exclude=java* kln*','smith','johns']
>>> [i for i in list1 if 'exclude' not in i]
['abc', 'oops', 'smith', 'johns']
>>>
simple method without list comprehension and effect in original list,
>>> list1=['abc','oops','#exclude=10','exclude=java* kln*','smith','johns']
>>> for i in filter(lambda x: 'exclude' in x, list1):
... list1.remove(i)
...
>>> list1
['abc', 'oops', 'smith', 'johns']
>>>
Related
This question already has answers here:
Remove all occurrences of a value from a list?
(26 answers)
Closed 1 year ago.
I want to remove the select element in sequence.
For example, I want to remove all 2 in sequence [1,2,3,2,3]
my code is
def remove_all(a_list, element):
for i in range(len(a_list)):
if element == a_list[i]:
a_list.remove(element)
return a_list
The output should be [1,3,3]
but the output of my code is [1,3,2,3]
I remove the first 2 but somehow the loop didn't go further to remove second 2. I wonder where is the problem of my code
Removing items in-place will almost certainly results in index errors.
[x for x in l if x != elem]
2 things.
You are modifying a list during iteration, I linked to a good read in my comment. also here
You return in the loop thus it stops at the return. Unindent the return, python is all about indentation unlike many other popular languages in this matter.
Try instead
Building another list for return:
def remove_all(a_list, element):
result = []
for ele in a_list:
if element != ele:
result.append(ele)
return result
Using a comprehension:
def remove_all(a_list, element):
return [ele for ele in a_list if ele != element]
a possible work-around is:
while element in a_list:
a_list.remove(element)
return element
But list comprehension works too, possibly even faster.
You should place the return after the loop finishes, something like:
def remove_all(a_list, element):
for i in a_list:
if element == i:
a_list.remove(element)
return a_list
a_list = [1, 2, 3, 2, 3]
result = remove_all(a_list, 2)
print(result)
Edit:
The code above does not work with the [2,2] case as pointed out in the comments.
Another solution would be:
myList = [2,2]
myList = list(filter((2).__ne__, myList))
print(myList)
Like that you don't copy the list anywhere, just is the list you are working on avoiding a list copy that can be expensive.
The __ne__ function checks that the element exists in the list returning True or False.
This question already has answers here:
Removing from a list while iterating over it [duplicate]
(5 answers)
Closed 6 years ago.
In a list, I have duplicate elements that I want to remove.
The following code doesn't work:
Note:
temp containts the list of indexes of elements that I want to remove.
x is my list.
temp = self.list_duplicates(x)
for index in tmp:
del x[index]
Build a new list with a comprehension:
x = [element for (i,element) in enumerate(x) if i not in temp]
If you want to remove only duplicates, i.e. leaving one copy of the original, there is a better way to do that:
from collections import OrderedDict
x = list(OrderedDict.fromkeys(x))
x.pop(index) will remove the item at index. However, x = [x[i] for i in range(len(x)) if x[i] not in x[:i]] will remove the duplicates more quickly.
No one addressed the first part of the question. So, for removing duplicate items its wise to use set(), it removes the duplicate items and returns a arbitrary list of unique items.
lst = [1,1,2,3,4,4]
new_lst = list(set(lst))
print(lst)
It will return unique list of elements in an arbitrary manner Eg : [1,4,2,3]
You can filter the list with the following:
Edit: Works now for list of indices
x = list(filter(lambda item: x.index(item) not in temp, x))
Here i want remove items in list of list by index.
Input is
li = [[1,2,3,4],[5,6,7,8]]
Excepted output is
[[1,3,4],[5,7,8]]
What I'm tried is,
print [x.pop(1) for x in li]
You can use the del operator like this:
for sublist in list:
del sublist[1]
You actually removed the items in the given index but you printed out the wrong list. Just print li after you pop the items:
>>> [x.pop(1) for x in li]
>>> print li
However, do you really have to use list comprehensions? Because calling .pop() in a list comprehension will accumulate the removed items and creates a new, totally useless list with them.
Instead, you can just do the following:
>>> for lst in li:
... lst.pop(1)
pop, like del change the underlying list so you must explicitely loop through the sublists to remove second element and them print the modified list.
for l in li: del l[1]
print li
If on the other hand, you do not want to change the lists but directly print the result, you could use a list comprehension:
print [ (l[:1] + l[2:]) for l in li ]
This question already has answers here:
How can I verify if one list is a subset of another?
(14 answers)
Closed 7 years ago.
my question is pretty much as above:
if you have 2 lists as below, how can you check if all items in the first list are in the second list.
eg
list_one=[1,2,3]
list_two=[1,2,3,4]
my current attempt is just "if all list_one in list_two:"
but this condition never seems to be filled and so nothing further takes place. Any help would be appreciated thanks :)
The all() function is used to check if all the condition are satisfied .We are getting elements from list_1 and checking if that is available in list_2 if all are available then we print "yes"
list_one=[1,2,3]
list_two=[1,2,3,4]
if all(a in list_two for a in list_one):
print "yes"
You can use all with a generator expression, this will allow short-circuiting upon finding the first element that doesn't occur in your second list.
>>> list_one=[1,2,3]
>>> list_two=[1,2,3,4]
>>> all(i in list_two for i in list_one)
True
I simply create a difference of sets and check is length.
assert len(set([1,2,3]) - set([1,2,3,4])) == 0
Note that in boolean context empty sets (like any other containers) are falsy, so you can simply so something like:
if set(seq1) - set(seq2):
do_something()
>>> l1 = [1,2,3,4,5]
>>> l2 = [3,2,1,5,4]
>>> for i in l1:
... if i not in l2:
... print('doh')
You can check for individual items in the list_one.
count=0
for i in list_one:
if i in list_two:
count += 1
if count==len(list_one):
print("All items covered!")
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.