I am trying to get the value of j when name matches in i. But unfortunately all I am getting is the last element in Functions(). I guess this makes sense. But how is it possible to get value of j at the time name matches the list of GetFunctionName()'s?
Is there any one line code to do this?
func_ea = [j for i in [GetFunctionName(j) for j in Functions()] if name in i]
EDIT: Thanks eric for the solving the first problem
Would it be possible to reduce this further down to one liners?
def LocateBytesInFunctions(self, searchterm, *funcname):
foundaddress = []
for name in funcname:
func_ea = [i for i in Functions() if name in GetFunctionName(i)]
for startea in func_ea:
endea = GetFunctionAttr(startea, FUNCATTR_END)
self.debugprint("Start: " + hex(startea) + " End: " + hex(endea))
foundaddress.extend(self.LocateBytes(searchterm, startea, endea))
return foundaddress`
Since i is only used in one place, you can expand the inner comprehension:
func_ea = [j for j in Functions() if name in GetFunctionName(j)]
The inner comprehension is running to completion, so j is getting bound to the last result from Functions(). One way to fix this is to keep both j and GetFunctionName(j) around so that you can reference it later in the comprehension loop.
func_ea = [j for i, j in [(GetFunctionName(j), j) for j in Functions()]
if name in i]
Related
Take the following code as an example:
a = [['James Dean'],['Marlon Brando'],[],[],['Frank Sinatra']]
n = 0
for i in a:
print a[n][0]
n = n + 1
I seem to be getting an error with the index value:
IndexError: list index out of range
How do I skip over the empty lists within the list named a?
Simple:
for i in a:
if i:
print i[0]
This answer works because when you convert a list (like i) to a boolean in an if statement like I've done here, it evaluates whether the list is not empty, which is what you want.
You can check if the list is empty or not, empty lists have False value in boolean context -
for i in a:
if i:
print a[n][0]
n = n + 1
Also, instead of using n separately, you can use the enumerate function , which returns the current element as well as the index -
for n, i in enumerate(a):
if i:
print a[n][0] # though you could just do - print i[0]
You could either make a test, or catch the exception.
# Test
for i in a:
if a[n]:
print a[n][0]
n = n + 1
# Exception
for i in a:
try:
print a[n][0]
except IndexError:
pass
finally:
n = n + 1
You could even use the condensed print "\n".join(e[0] for e in a if e) but it's quite less readable.
Btw I'd suggest using using for i, element in enumerate(a) rather than incrementing manually n
Reading your code, I assume you try to get the first element of the inner list for every non empty entry in the list, and print that. I like this syntax:
a = [['James Dean'],['Marlon Brando'],[],[],['Frank Sinatra']]
# this filter is lazy, so even if your list is very big, it will only process it as needed (printed in this case)
non_empty_a = (x[0] for x in a if x)
for actor in non_empty_a : print (actor)
As mentioned by other answers, this works because an empty list is converted to False in an if-expression
I would like to find the smallest value of list a. I know that there is a function like min() to find the value but I would like do it work with a for-loop.
I get the error Index out of range with the if-Statement, but I don't know why.
a = [18,15,22,25,11,29,31]
n = len(a)
tmp = a[0]
for i in a:
if(a[i] < tmp):
tmp = a[i]
print(tmp)
When you iterate over a list in Python (for e in l:), you do not iterate over the indices but over the elements directly. So you should write:
for e in a:
if(e < tmp):
tmp = e
print(tmp)
As already said, you mixed iteration over elements and looping over indexes. The solution for iteration over elements was already presented, so for completeness I would like to write the other solution:
a = [18,15,22,25,11,29,31]
n = len(a)
tmp = a[0]
for i in range(n):
if(a[i] < tmp):
tmp = a[i]
print(tmp)
Edit: changed xrange to range as per comment bellow.
Hello folks am new to python development.I have wrote a sample code:
mylist = ['something','baby','car']
for i,n in mylist:
mylist[i] = mylist[i]+1
print i,n
I know i is the index in the list so it will execute up to the number of elements in the list.But when I execute the script I get type error...
In this code the index of the list is inceremented by one... So the expected result is.
0 something
1 baby
2 car
Instead of that i got a typeerror..Please help me in solving this..Any help would be appreciated..Thanks
Very close, just missing enumerate--
for i,n in enumerate(mylist):
However, the code above will attempt to add an integer to a string; this will throw a new error. If you are trying to push elements back, you would want mylist[i] = mylist[i+1] (note you would have to have a case to catch the last element)
This :
mylist = ['something','baby','car']
for i,n in mylist:
mylist[i] = mylist[i]+1
print i,n
raises a ValueError ("Too many values to unpack") on the second line.
If you just add enumate on this second line, ie for i,n in enumerate(mylist):, then you get a TypeError on the next line, because you are trying to add a string (mylist[i]) and an integer (i). The point is: what you want to increment is i, not mylist[i] (which is the same thing as n fwiw), so it should be:
for i, n in enumerate(mylist):
i = i + 1
print i, n
BUT you don't have to go thru such complications to print out "index+1 : item at index+1", all you need is to pass the optional start argument to enumerate:
mylist = ['something','baby','car']
for i, n in enumerate(mylist, 1):
print i, n
I've got a loop issue in Python 2.72 that's really frustrating me. Basically the loop is not iterating on the first index j, and I've tried all sorts of ways to fix it with no luck.
def learn(dataSet):
for i in dataSet.getNext():
recall = raw_input("Enter all members of %s you are able to recall >>> (separated by commas) " % (i.getName()))
missed = i.getMembers()
missedString = []
for a in missed:
missedString.append(a.getName())
Here is the loop I can't get to iterate. The first for loop only goes through the first iteration of j in the split string list, then removes it from missedString. I would like for all members of the split-string recall to be removed from missedString.
for j in string.split(recall, ','):
if j in missedString:
missedString.remove(j)
continue
for b in missed:
if b.getName() not in missedString:
missed.remove(b)
print 'You missed %d. ' % (len(missed))
if (len(missed)) > 0:
print 'Maybe a hint or two will help...'
for miss in missed:
remind(miss.getSecs(), i.getName(), missed)
How can I fix the above code?
missedString is a terrible name for a list
Note that you can simplify your code in a few places
missedString = []
for a in missed:
missedString.append(a.getName())
can be replaced by a list comprehension
missedString = [a.getName() for a in missed]
Here you should just use the split method of recall instead of string.split). It looks as though this loop is supposed to be nested inside the for i loop, so I will assume it is (If it's not, you will be using the wrong value of recall with the wrong dataset).
for j in string.split(recall, ','):
if j in missedString:
missedString.remove(j)
continue
It can also be replaced by a list comprehension.
recall_set = set(recall.split(','))
missedString = [j for j in missedString if j not in recall_set]
This will not work properly if eg. the user enters extra spaces in the input, so it's a good idea to strip() those elements
recall_set = set(s.strip() for s in recall.split(','))
missedString = [j for j in missedString if j not in recall_set]
This loop has a serious problem. In general it's not a good idea to remove elements from the list you are iterating over. You'll end up skipping over some elements without checking them
for b in missed:
if b.getName() not in missedString:
missed.remove(b)
Maybe a list comprehension can help again
missed = [b for b in missed if b.getName() in missedString]
In this code
for j in string.split(recall, ','):
if j in missedString:
missedString.remove(j)
continue
try adding an
else:
print 'Didn't remove "%s"' % j
(And get rid of the continue. It's not serving any purpose).
You probably are missing some whitespace from your split. If that's the case, add a j = j.strip() or use re.split(r'\s*,\s*', recall) in place of string.split(recall, ',').
Hey, I was trying to delete an item form a list (without using set):
list1 = []
for i in range(2,101):
for j in range(2,101):
list1.append(i ** j)
list1.sort()
for k in range(1,len(list1) - 1):
if (list1[k] == list1[k - 1]):
list1.remove(list1[k])
print "length = " + str(len(list1))
The set function works fine, but i want to apply this method. Except I get:
IndexError: list index out of range
on the statement:
if (list1[k] == list1[k - 1]):
Edited to add
(Thanks to Ned Batchelder) the working code is:
list1 = []
for i in range(2,101):
for j in range(2,101):
list1.append(i ** j)
list1.sort()
k = 0
while k < len(list1) - 1: # while loop instead of for loop because "The range function is evaluated once before the loop is entered"
k += 1
if (list1[k] == list1[k - 1]):
list1.remove(list1[k])
list1.sort()
k -= 1 # "If you find a duplicate, you don't want to move onto the next iteration, since you'll miss potential runs of more than two duplicates"
print "length = " + str(len(list1))
Your code doesn't work because in your loop, you are iterating over all the indexes in the original list, but shortening the list as you go. At the end of the iteration, you will be accessing indexes that no longer exist:
for k in range(1,len(list1) - 1):
if (list1[k] == list1[k - 1]):
list1.remove(list1[k])
The range function is evaluated once before the loop is entered, creating a list of all the indexes in the list. Each call to remove shortens the list by one, so if you remove any elements, you're guaranteed to get your error at the end of the list.
If you want to use a loop like this, try:
k = 1
while k < len(list1):
if list1[k] == list1[k-1]:
del list1[k]
else:
k += 1
I fixed a few other things:
You don't need parentheses around the condition in Python if statements.
If you find a duplicate, you don't want to move onto the next iteration, since you'll miss potential runs of more than two duplicates.
You want to start from index 1, not zero, since k=0 will access list1[-1].
It looks as if you're trying to uniquify a list (clarification would be awesome) so take a look here: http://www.peterbe.com/plog/uniqifiers-benchmark
There is also this question here on SO: In Python, what is the fastest algorithm for removing duplicates from a list so that all elements are unique *while preserving order*?
Instead of removing items Write a list comprehension of the things you want in the new list:
list1[:] = [list1[k] for k in range(1,len(list1) - 1)
if not list1[k] == list1[k - 1] ]
Your method breaks because you remove items from the list. When you do that, the list becomes shorter and the next loop iteration has skipped a item. Say you look at k=0 and L = [1,2,3]. You delete the first item, so L = [2,3] and the next k=1. So you look at L[1] which is 3 -- you skipped the 2!
So: Never change the list you iterate on
You can use del :
l = [1, 2, 3, 4]
del l[2]
print l
[1, 2, 4]