I have a list as following:
list=[80,"error",100,74,72,71,"error",39,38,63,"error",82,"error",62,75,23,77,87,"error",36]
and I want to remove "error" from the list :
llist=len(list)
for i in range(llist):
if list[i]=="error":
del list[i]
llist-=1
print(list)
but the compiler still display,"if list[i]=="error":
IndexError: list index out of range".
Where am I wrong?
Thanks in advance!
First don't use keyword list as variable name. Then conditional list comprehension is an easy way to do it:
my_list = [i for i in my_list if i != "error"]
Your problem here is that you are modifying the list length while trying to iterate over it. Perfect recipe for errors...
Your fix:
llist=len(list_)
for i in range(llist):
try:
if list_[i]=="error":
del list_[i]
llist-=1
except IndexError:
pass
print(list_)
OUTPUT:
[80, 100, 74, 72, 71, 39, 38, 63, 82, 62, 75, 23, 77, 87, 36]
Suggested:
Looks like you only need the numbers from the list:
import numbers
print([x for x in list_ if isinstance(x, numbers.Number)])
OUTPUT:
[80, 100, 74, 72, 71, 39, 38, 63, 82, 62, 75, 23, 77, 87, 36]
OR:
print([num for num in list_ if isinstance(num, (int,float))])
Try using remove function.
l = ['a', 'b', 'error', 'c']
l.remove('error')
Try this :
list1 = [i for i in list1 if i != 'error']
Try :
>>> list1=[80,"error",100,74,72,71,"error",39,38,63,"error",82,"error",62,75,23,77,87,"error",36]
>>> filter(lambda a: a != "error", list1)
[80, 100, 74, 72, 71, 39, 38, 63, 82, 62, 75, 23, 77, 87, 36]
In the last line, you're using "print(list)" but list is not your variable, even list can't be a variable.
You're changing the list after remove a element, dont do it. With the remove element is ready
Related
I get a list of values from a source. And I also have a dictionary of the standard values. I need to remove any value in the list that is not found in the dictionary.
I wrote this code just to test how it works:
alist = [47, 64, 69, 37, 76, 83, 95, 97]
adict = {'A':47, 'B':69, 'C':76, 'D':97}
list2 = list(adict.values())
for i in alist:
if i not in list2:
alist.remove(i)
print(list2,alist)
The output is:
[47, 69, 76, 97] [47, 69, 76, 95, 97]
What I don't understand here is why the value 95 stayed in the new alist generated?
When I check presence of 95 in the list2, it shows correct results as under:
INPUT:
print(95 in list2)
OUTPUT:
False
If I manually remove 95 from the list using alist.remove(95), it does get removed.
So, can anyone please help me understand where I have gone wrong here.
Thanks.
You are removing items of the container on which you are iterating so it is escaping the items. That's why 95 is never got visited and remains in the list.
Try to run below version of your own code... You will get to know how actually the value of 'i' is changing.
alist = [47, 64, 69, 37, 76, 83, 95, 97]
adict = {'A':47, 'B':69, 'C':76, 'D':97}
list2 = list(adict.values())
print("list2: ", list2)
print("alist: ", alist)
print("\n\n for loop")
for i in alist:
print("in loop: ")
print("alist: ", alist)
print("i: ", i)
print("list2: ", list2)
if i not in list2:
print("removing ", i)
alist.remove(i)
print("\n")
print(list2,alist)
See below how to filter the list.
The general problem with the approach in your code is that you manipulate the list while you iterate over it.
Dont do that - the results are unexpected.
alist = [47, 64, 69, 37, 76, 83, 95, 97]
adict = {'A': 47, 'B': 69, 'C': 76, 'D': 97}
filtered = [x for x in alist if x in set(adict.values())]
print(filtered)
output (Note that 95 is not in the new list)
[47, 69, 76, 97]
You are modifying the iterating object. When you iterate over any iterable object, never ever change the iterating object during the iteration.
For your case, you may simply use & in set
alist = [47, 64, 69, 37, 76, 83, 95]
adict = {'A':47, 'B':69, 'C':76, 'D':97}
set1 = set(alist)
set2 = set(adict.values())
alist = list(set1 & set2)
print(alist)
output: [47, 69, 76], I removed the case 97 intentionally.
Your program is correct logically. Because if only executes when the given condition is True .
Now, your condition is: if i not in list2:
So the program will accept any value other than the items of list2 .
print(95 not in list2)
will give you True output and that's why if statement is executing it.
Given a list:
lis = [37.21, 37.21, 37.2, 44, 44, 44, 101, 101]
What is a simple way to extract the second-largest elements?
[44, 44, 44]
My attempt
lis = [37.21, 37.21, 37.2, 44, 44, 44, 101, 101]
def sublist_of_second_largest(lis):
maxx=max(lis)
n=lis.count(maxx)
for i in range(n):
lis.remove(maxx)
maxx=max(lis)
n=lis.count(maxx)
out=[]
for i in range(n):
out.append(maxx)
return out
print(sublist_of_second_largest(lis))
Simple pythonic way:
lis = [37.21, 37.21, 37.2, 44, 44, 44, 101, 101]
num = sorted(set(lis), reverse=True)[1]
print([i for i in lis if i == num])
Ouput:
[44, 44, 44]
While Zain's answer is correct and consice, due to the sorting it has an O(n log n) runtime. This might not matter to you, but if it does here is an O(n) implementation:
def sublist_of_second_largest(num_lst):
num_set = set(num_lst)
num_set.remove(max(num_set))
snd_largest_num = max(num_set)
return [val for val in num_lst if val == snd_largest_num]
print(sublist_of_second_largest([37.21, 37.21, 37.2, 44, 44, 44, 101, 101]))
Prints:
[44, 44, 44]
first i used a list methods remove() to delete the item that doesn't exist in the dictionary values.
The code is like this:
rollNumber = [47, 64, 69, 37, 76, 83, 95, 97]
sampleDict = {'Jhon':47, 'Emma':69, 'Kelly':76, 'Jason':97}
for num in rollNumber:
if num not in sampleDict.values():
rollNumber.remove(num)
print('After removing unwanted element from list', rollNumber)
output : [47,69,76,95,97]
this is wrong answer
the second one i made a empty list and used append() methods from the item that in dictionary.values
the code is like this:
rollNumber = [47, 64, 69, 37, 76, 83, 95, 97]
sampleDict = {'Jhon':47, 'Emma':69, 'Kelly':76, 'Jason':97}
new = []
for num in rollNumber:
if num in sampleDict.values():
new.append(num)
print('After removing unwanted element from list', new)
output : [47,69,76,97]
this the correct answer
Do you guys know why this happens?
I think that the problem is that you are deleting elements while iterating it. You're better off using a list comprehension:
rollNumber = [47, 64, 69, 37, 76, 83, 95, 97]
sampleDict = {'Jhon':47, 'Emma':69, 'Kelly':76, 'Jason':97}
rollNumber = [num for num in rollNumber if num in sampleDict.values()]
print('After removing unwanted element from list', rollNumber)
Outputs:
After removing unwanted element from list [47, 69, 76, 97]
Instead of mutating the list, try using a comprehension to generate a new list
In [2]: vals = list(sampleDict.values())
In [3]: out = [v for v in rollNumber if v in vals]
In [4]: out
Out[4]: [47, 69, 76, 97]
You try to modify a list while iterating on it, this is a common mistake.
Your 2nd way is the correct one, which can be written this way:
print([num for num in rollNumber if num in sampleDict.values()])
Since you are removing the element, it is not impacting the index of for loop and the for loop is skipping some list element due to the changed position of index once the number is removed.
rollNumber = [47, 64, 69, 37, 76, 83, 95, 97]
sampleDict = {'Jhon': 47, 'Emma': 69, 'Kelly': 76, 'Jason': 97}
for num in rollNumber:
print(num)
if num not in sampleDict.values():
rollNumber.remove(num)
print(rollNumber)
print('After removing unwanted element from list', rollNumber)
Result
47
64
[47, 69, 37, 76, 83, 95, 97]
37
[47, 69, 76, 83, 95, 97]
83
[47, 69, 76, 95, 97]
97
After removing unwanted element from list [47, 69, 76, 95, 97]
As you can see in the result for loop does not get executed for 69, 76 and 95 due to change in their index.
I have a list with around 60000 characters.
The package I'm using takes only lists above 999 characters...
So for this example I have to run the function 60000/999 = 61 times.
Here is how a list looks like as an example:
liste=[ 'item1', 'item2', 'item3', 'item4'...]
Here is the issue, this number of characters will not be the same over time it can be less or more, so I have to take the length of the list into account.
Here is the code I'll use:
ids = function(liste)
for id in ids:
print(id)
I guess an idea should be to do a list of lists, the first big one including the 61 lists of 999 characters for each one and then do a loop:
for lists in list:
ids = function(lists)
for id in ids:
print(id)
Does someone have a better idea and/or knows how to create a list of lists depending on the length of the first big list?
It sounds like you want to process a long list in shorter chunks. You don't need to pre-process the list into a list of short lists. Here's a generator to break a list into sublists. Adapt as needed:
# Quick way to create a long list of numbers.
# I used a size that isn't a multiple of the chunk size to show that it doesn't matter.
items = list(range(105))
# Function to return smaller lists of the larger list.
def chunk(items,n):
for i in range(0,len(items),n):
yield items[i:i+n]
# Break the larger list into length 10 lists.
for subitems in chunk(items,10):
print(subitems) # process as you want...
Output:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
[20, 21, 22, 23, 24, 25, 26, 27, 28, 29]
[30, 31, 32, 33, 34, 35, 36, 37, 38, 39]
[40, 41, 42, 43, 44, 45, 46, 47, 48, 49]
[50, 51, 52, 53, 54, 55, 56, 57, 58, 59]
[60, 61, 62, 63, 64, 65, 66, 67, 68, 69]
[70, 71, 72, 73, 74, 75, 76, 77, 78, 79]
[80, 81, 82, 83, 84, 85, 86, 87, 88, 89]
[90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
[100, 101, 102, 103, 104]
So your code would look something like:
for sublist in chunk(liste,999):
taxids = accession.taxid(sublist)
for tax in taxids:
print(tax)
You seem to be new to Python. While creating lists in python, you don't need to give a length for that list. Why make a list of lists when you can make a list of strings, and still use it as a list of string? So, you DON'T have to the length into account.
I am not very clear about the question you asked, so correct me if I'm wrong. Also, I'm assuming that accession is a user-made function (made by you), to add new elements to the list.
Following is the code for an already defined liste
# I am assuming the list 'liste' is already defined
taxids = []
for i in liste:
taxids.append(list(i))
print(taxids)
Following is the code for when you want take inputs directly
n = input("no. of inputs that are to be given(the no. of elements that you need in the list): ")
for i in range():
elem = input("Enter the string: ")
taxids.append(list(elem))
print(taxids)
Let me know if this help!
I have a problem writing the following arrays to a .txt file.
This is my code:
for i in range(len(my_particles)):
list = []
list.append(my_particles[i].n)
for z in range(len(my_particles[i].neighbours)):
list.append(my_particles[i].neighbours[z])
#for i in range(len(list)):
print >>f, list
f.close()
This is the output:
[0, 2, 20, 91, 114, 127]
[1, 6, 24, 114]
[2, 0, 65, 73, 91, 114]
[3, 71, 91, 120]
[4, 16, 69, 104]
[6, 1, 25, 87, 100, 114]
[7, 19, 83, 111]
[9, 38, 59, 72, 76]
[11, 56, 101, 108]
[12, 86, 92, 126]
[13, 30, 79, 82, 101, 104]
[14, 78, 103, 124]
[15, 23, 44, 90, 116]
[16, 4, 97, 106, 108]
[17, 19, 85, 111]
[18, 47, 60, 68, 74]
Is there a way to print it in this format?
0, 2, 20, 91, 114, 127
1, 6, 24, 114
I have tried
print>>f, "".join(list)
But it does not work, as it is a list of numpy64 floats.
You want to make strings out of each member of the list first. Try
print >>f, ', '.join(map(str,list))
Also, don't name variables list!
Try
",".join(str(i) for i in list))
hacky fix:
print(str(list).replace(']','').replace('[',''))
Converting them to strings should work
print >>f, ', '.join(str(elem) for elem in my_list)
and as Brien said, don't call your list list
If list is a numpy array of floats:
list.astype('str')
OR-You can also use csv to write np.arrays quickly:
import csv
import numpy as np
a = np.random.uniform(0,10,size = (5,5))
writer = csv.writer(open('txtfile.txt','wb'))
writer.writerows(a)
Yields txt file:
3.55183065126,1.05649949199,5.15510365109,1.0369928554,7.66646909667
9.5145737219,1.53877245296,5.53917128683,1.55343228883,8.78227048275
5.80408228776,2.58788175555,0.502704494319,1.63833152952,3.59898531148
2.94430872526,2.42069917781,5.75920106752,2.42453222446,1.73308148034
1.9579612159,0.609573767011,3.87717828624,7.86853109668,7.41038950637
or if you wanted integers, adding:
writer.writerows(a.astype(int))
would yield
2,0,3,4,1
9,5,4,4,3
9,7,6,4,2
3,5,7,2,0
6,0,2,7,7
Firstly, you should use the with statement when dealing with files to ensure they are automatically closed even if the program encounters an error befor they finish. Secondly, you can replace for i in range(len(my_list)) and my_list[i] with for i in my_list and i. Also, having a variable called list overwrites the inbuilt type list. Common practice is to use a trailing underscore to avoid this.
This code should work (although I don't currently have Numpy installed to test it with)
with open("myfilename.txt","w") as f:
for i in my_particles:
list_ = []
list_.append(i.n)
for j in value.neighbours:
list_.append(j)
f.write(", ".join(str(n) for n in list_))
Note that this will erase the previous contents of the file. If you don't want this, open the file with "a" in the open function rather than "w".