delete list element by index while iterating using python [duplicate] - python

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))

Related

I want to use list comprehension for this code in python [duplicate]

This question already has answers here:
Get difference between two lists with Unique Entries
(32 answers)
Closed 8 months ago.
I have two lists lst and count I need enumerate on lst and check if lst elements exists in count or not if not then append it in another list else pass.
for i, u in enumerate(lst ):
if u in count:
pass
else:
_ = sku[i].pop("_id")
objects.append(sku[i])
I need this code to be in one line
What's the content of lst, count, sku and objects before this code?
If I assume that these data are: list, list, list of dicts and empty list, you can maybe do something like this:
objects = [{k: v for k, v in sku[i].items() if k != i} for i, u in enumerate(lst) if u not in count]
It's one line, but it's not readable nor understandable!
I don't recommend you using one-line or comprehension list for such complex method.

Exclude an element in a list [duplicate]

This question already has answers here:
Slicing out a specific from a list
(2 answers)
Index all *except* one item in python
(11 answers)
Closed 2 years ago.
Is it possible to use slice but on a specific element on a list? For example a = [1,2,3,4,5,6,7,8,9] I want to make a for loop that prints out the whole list except the second element.
I want to make something like this:
for i in a[something_slice]:
print(i)
Is this possible?
For excluding just one element, the 2 slice lst[:i] + lst[i + 1:] approach proposed by #Applet123 is probably the fastest (Or perhaps a excluded = lst.pop(1) to extract the excluded element and for x in lst: print(x) for printing all the others; then lst.insert(1,excluded) to put the excluded element back on the list. See data structures docs for details).
If you just want to filter out certain indexes, instead of a for loop I recommend you use a more pythonic (and intuitive) approach based on list comprehensions and enumerate:
myList = [1,2,3,4,5,6,7,8,9]
excludedIndices = [1]
myFilteredList = [x for i, x in enumerate(myList) if i not in excludedIndices]
print (myFilteredList)
# output:
# [1,3,4,5,6,7,8,9]
# or, to actually print each element individually:
for x in myFilteredList:
print (x)
# which can also work as a 2-liner with inline filtering:
for i, x in enumerate(myList):
if i not in excludedIndices: print(x)
Also check out python usage of filter and map builtin functions, which may be overkill for this purpose but still offer a general and more powerful solution for this kind of processing:
# filters an enumerated element
def myFilter(element):
return element[0] not in excludedIndices
# maps an enumerated element to a function
def myMap(element):
print(element[1])
# runs myMap function for each enumerated element on the list filtered by myFilter
for x in map(myMap,filter(myFilter,enumerate(myList))): pass
Which you can also turn into a one-liner using lambda expressions:
for x in map(lambda x: print(x[1]),filter(lambda x: x[0] not in excludedIndices,enumerate(myList))): pass
you can do it without slicing, using enumerate()
index_to_skip=1
for idx,item in enumerate(a):
if idx!=index_to_skip:
print(item)
If you actually want to slice the list, you can use 2 slices to slice around it:
def exclude(lst, i):
return lst[:i] + lst[i + 1:]
exclude([1, 2, 3, 4, 5], 1) # [1, 3, 4, 5]
If you just want to loop through it, you could alternatively just skip when the index reaches the value you want to skip:
for i, v in enumerate(a):
if i == 1:
continue
print(v)

convert a list of lists to a list of strings [duplicate]

This question already has answers here:
How do I make a flat list out of a list of lists?
(34 answers)
Closed 2 years ago.
I want to convert this list of list to list of strings here.
The idea behind converting is to remove the duplicates from the output.
Here is the original list: (The output from json.loads(file.json))
I have further simplified the dictionary output and got here a list of keys.
> [[u'xyza'], [u'xyzb'], [u'xyzc', u'xyzd', u'xyze', u'xyzf', u'xyzg',
> u'xyzh'], u'xyzd', [u'xyza'],[u'xyxv']]
Now the list of keys contain another list inside it in some keys and duplicates as well.
I tried to convert this list of lists to a list of strings using something like
> [','.join(x) for x in list01]
But that did not work for me as i also got some single characters in the output as well like ['xyza'. 'x', 'y',...]
How will I be able to parse the list data here to get an output something like
['xyza', 'xyzb', 'xyzc',...,'xyzx']
since you have a list of list and string in it and you want list of string with no duplicate present.
create a resultant list, and then iterate through the parent list and check the type of each object, if it of type list then iterate through the sublist and check that string in sublist is present in the resultant list or not, if present then ignore else if not present then add it to list, same goes for the parent list iterate when it is not of type list.
res = [[u'xyza'], [u'xyzb'], [u'xyzc', u'xyzd', u'xyze', u'xyzf', u'xyzg', u'xyzh'], u'xyzd', [u'xyza'],[u'xyxv']]
result =[]
for i in res:
if isinstance(i, list):
for j in i:
if j not in result:
result.append(j)
else:
if i not in result:
result.append(i)
print(result)
output:
['xyza', 'xyzb', 'xyzc', 'xyzd', 'xyze', 'xyzf', 'xyzg', 'xyzh','xyxv']
if you want to make it little faster, then instead of result as list , you can create it as a dictionary and without checking the condtition if string already present or not, you just update the dictionary and once you iterate through whole list, convert the dictionary keys to list and that is your answer.
You can try this:
mylist = [[u'xyza'], [u'xyzb'], [u'xyzc', u'xyzd', u'xyze', u'xyzf', u'xyzg', u'xyzh'],` u'xyzd', [u'xyza'],[u'xyxv']]
new_list = []
for i in mylist:
if isinstance(i, list):
for j in i:
new_list.append(j)
else:
new_list.append(i)
remove duplicates:
new_list = list(set(new_list))
output:
['xyzc', 'xyzf', 'xyze', 'xyzg', 'xyxv', 'xyza', 'xyzh', 'xyzb', 'xyzd']
Not all items are lists itself so this should be checked. Also, turn to a set and back to a list for unique values:
l = [[u'xyza'], [u'xyzb'], [u'xyzc', u'xyzd', u'xyze', u'xyzf', u'xyzg', u'xyzh'], u'xyzd', [u'xyza'],[u'xyxv']]
new_list = []
for sublist in l:
if isinstance(sublist, list):
for item in sublist:
new_list.append(item)
else:
new_list.append(sublist)
new_list = list(set(new_list))
>>> new_list
['xyzc', 'xyza', 'xyzd', 'xyzb', 'xyzh', 'xyxv', 'xyzg', 'xyzf', 'xyze']
Let's call your list of lists the variable values
def to_str_list(values):
vars = list()
for x in values:
while type(x[0]) == list:
x = x[0]
for s in x:
if s not in vars:
vars.append(s)
return vars
[d['value'] for d in l]
If value might be missing, you can use
[d['value'] for d in l if 'value' in d]

Remove particular similar element from the list in python [duplicate]

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']
>>>

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