This question already has answers here:
How to remove items from a list while iterating?
(25 answers)
Closed 5 years ago.
I have a list which consist of string and integers. I have to pop only integers and put that in a separate list. My code:
list1=['a','b','c','d','e','f','g','h',1,2,3]
list=[]
x=0
for i in list1:
if isinstance(i,int) :
list.append(i)
list1.pop(x)
x += 1
print(list1)
print(list)
Output of above code
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 2]
[1, 3]
My question is: Why are all the integers not removed by my code? What is wrong with my code?
You iterate and manipulate the same list at the same time:
for i in list1: # iteration
if isinstance(i,int):
list.append(i)
list1.pop(x) # manipulate
x += 1
This usually does not work: the for loop works with a cursor. If you meanwhile removes an item, you thus will start skipping elements.
It is better to simply use a declarative and Pythonic approach, like for instance the following:
list_int = [i for i in list1 if isinstance(i,int)]
list1 = [i for i in list1 if not isinstance(i,int)]
Furthermore you should not name a variable list, since then you remove the reference to the list class.
Related
This question already has answers here:
How to remove items from a list while iterating?
(25 answers)
Closed 24 days ago.
I have an item in list that contains just a quotation mark and a comma (",) and I can't seem to pop that item from the list
I've tried
for item in my_list:
if item == '",':
my_list.pop(my_list.index(item))
I've also tried
for item in my_list:
if item == '\",':
my_list.pop(my_list.index(item))
I've gotten no luck, is there anything I'm missing
Your code has two issues:
Typically it is frowned upon to modify an iterable while iterating over it. You can iterate over a copy of the list instead, and then modify the original list.
You are trying to compare item1 to something, but item1 is not defined. You should change this to item.
Here is the modified code:
my_list = ['",', 'a', 'b', 'c']
for item in my_list.copy():
if item == '",':
my_list.pop(my_list.index(item))
print(my_list)
Output
['a', 'b', 'c']
Try the following:
element_to_remove = '",'
for _ in range(my_list.count(element_to_remove)):
my_list.remove(element_to_remove)
This question already has answers here:
Flatten an irregular (arbitrarily nested) list of lists
(51 answers)
How do I make a flat list out of a list of lists?
(34 answers)
Closed 3 months ago.
I have a list that looks similar to:
list = [[[a,b,c], e, f, g], h, i, j]
and my desired output is:
merged_list = [a,b,c,e,f,g,h,i,j]
does anyone know an efficient way to do this?
i tried to do some sort of merging lists with the sum function but it didn't work
first i make all your variable into string because it was giving me error of not defined
so here is the code
#you have 3 list in total
list = [[['a','b','c'], 'e', 'f', 'g'], 'h', 'i', 'j']
output_list = [] # created a empty list for storing the all data in list
for list2 in list: # you will get 2 list now
for list1 in list2:# you will get 1 list now
for i in list1: # now you will only have items in list
output_list.append(i) #adding all item in output_list one by one
print(output_list) # printing the list
This question already has answers here:
How to remove items from a list while iterating?
(25 answers)
Closed 6 months ago.
I am trying to write simple code to print an item of a list and remove it after printing:
list = ['a', 'b', 'c']
for i in list:
print(i)
list.remove(i)
But output is weird:
a
c
Why is output thay way?
When you iterate over a list, you get the items in order of their indices (item 0, item 1, item 2, etc). When you remove an item from a list, the indices of all the items after that shift by one.
In the first iteration, the list is ['a', 'b', 'c'], and i is list[0].
During the first iteration, you remove 'a'.
In the second iteration, the list is ['b', 'c'], and i is list[1]. You get 'c' instead of 'b' because 'c' is now at index 1.
If you want to remove each item as you iterate, the better approach would be to iterate in a while loop as long as the list contains items, and pop as you print:
my_list = ['a', 'b', 'c']
while my_list:
print(my_list.pop(0))
In many cases, it's better to do the thing you want to do in the iteration, and then clear the list:
for i in my_list:
print(i)
my_list.clear()
You're currently iterating while removing the items, if you want alter the list while reading it then probably you want to use the length "as index":
list = ['a', 'b', 'c']
while len(list):
# pop does what you want: read the element at index [i] and remove it from the list
print(list.pop(0))
Output:
a
b
c
Explanation
the reason the output seems strange it's because you are removing items when iterating over a list.
the problem here is that python iterates checking for the index.
Consider this example:
lst = [32,43,2]
for x in lst:
lst.pop(0)
print(x,lst)
Outputs
32 [43, 2]
2 [2]
here you can see the problem. in the first iteration it took the first item that was removed, all ok. The problem starts with the second iteration.
The iterator thinks the index to go is 1 (2nd element) but it's actually the 1st since the first element was removed.
You can fix it also by iterating the reversed list as the index cannot change.
also see this question for more information
Possible solutions
You should iterate over a copy instead:
for x in mylist.copy():
mylist.remove(x)
You could also use a while loop and list.pop.
while mylist:
print(mylist.pop(0))
Advice
Before leaving, I would like to give some advice.
Don't use builtin as variable names, it causes confusion and could cause conflict in your code if it uses those builtin names.
I would advice to clear the list after the loop using the list.clear() method.
Use the list.pop method if you want to know a value and remove it at the same time.
Useful links
python datastructures official documentation
python list w3school
linuxhint python list methods
This question already has answers here:
Generate a random derangement of a list
(7 answers)
Closed 6 years ago.
I would like to random shuffle a list so that each variable in the list when shuffled gets put in a new place in the list.
What I am currently doing:
list = ['a', 'b','c', 'd'];
random.shuffle(list)
list
['c','b','d','a']
With this method I shuffle the list but it is still possible to have a variable end up in the same place in this case 'b'.
My desired output
completely shuffled list
['c','a','d','b']
I appreciate any help. I am new to python but please let me know if any further information is needed.
Something like this should do what you want:
import random
import copy
def super_shuffle(lst):
new_lst = copy.copy(lst)
random.shuffle(new_lst)
for old, new in zip(lst, new_lst):
if old == new:
return super_shuffle(lst)
return new_lst
Example:
In [16]: super_shuffle(['a', 'b', 'c'])
Out[16]: ['b', 'c', 'a']
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Modifying list while iterating
I have been given a task to make a code in python that will remove all members that occures more than once in a list and leave 1 copy of it.
Condition: it should be case-insesitive
So I've written down the following code:
string = raw_input()
list1 = string.split(",")
low_case_list = list1[:] #for case-insesitive
for i in range(len(low_case_list)):
low_case_list[i] = low_case_list[i].lower()
for member in low_case_list:
if(low_case_list.count(member) > 1):
del list1[low_case_list.index(member)]
del low_case_list[low_case_list.index(member)]
after the input I get this list: [a,b,c,d,A,B,C,D,a,b,c,d]
and after I do the operation on it: [B,D,a,b,c,d]
my question is, why it skips 'B' and 'D' when it removes the members?
Why not just convert your list into a set with all elements converted to lower-case, and then back to a list. You can use a generator for converting every element to lowercase.
You can do it like this: -
>>> l = ['a', 'b', 'c', 'A', 'B', 'C', 'a', 'b', 'c']
>>> new_list = list(set(elem.lower() for elem in l))
>>> new_list
['a', 'c', 'b']
Note that, order may be changed because, set does not maintain the order of it's elements.
You could try something like this instead:
input = raw_input().split(',')
unique = set([s.lower() for s in input])
result = list(unique)
Try this, should be simple.
Given your list li:
lowcase = [elem.lower() for elem in li]
output = []
for el in lowcase:
if el not in output: output.append(el)
return output # if necessary, otherwise a simple li = output
Or, in a faster and more elegant way, you could replace the whole for loop with:
[output.append(el) for el in lowcase if el not in output]
Your code should be buggy because you refer to the index of the element, but the list changes size during the loop, so indices change too.
EDIT: didn't think about sets, obviously they're the best solution here.