Inline for loop

I am trying to learn neat pythonic ways of doing things and wondered why my cycle loop cannot be reorganized as follows:

q = [1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5] vm = [-1, -1, -1, -1] for v in vm: if v in q: p.append(q.index(v)) else: p.append(99999) vm[p.index(max(p))] = i 

I tried replacing the for loop with:

 [p.append(q.index(v)) if v in q else p.append(99999) for v in vm] 

But that will not work. for v in vm: loop for v in vm: crowds out numbers from vm based on when they appear in q .

+7
python syntax list-comprehension
source share
4 answers

What you use is called list comprehension in Python, not the built-in for-loop (although it looks like one). You should write your loop as a list comprehension as follows:

 p = [q.index(v) if v in q else 99999 for v in vm] 

When using list comprehension, you do not call list.append because the list is created from the comprehension itself. Each item in the list will be what is returned by the expression to the left of the for keyword, which in this case is q.index(v) if v in q else 99999 . By the way, if you use list.append inside the comprehension, then you will get a list of None values, because it always returns the append method.

+11
source share

you can use enumerate by maintaining the ind / index in vm, if you do vm a set you will also have a search of 0(1) :

 vm = {-1, -1, -1, -1} print([ind if q in vm else 9999 for ind,ele in enumerate(vm) ]) 
+2
source share

your comphresnion list will work, but will return a None list, because append return None:

demo:

 >>> a=[] >>> [ a.append(x) for x in range(10) ] [None, None, None, None, None, None, None, None, None, None] >>> a [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 

best way to use it as follows:

 >>> a= [ x for x in range(10) ] >>> a [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
+2
source share
 q = [1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5] vm = [-1, -1, -1, -1,1,2,3,1] p = [] for v in vm: if v in q: p.append(q.index(v)) else: p.append(99999) print p p = [q.index(v) if v in q else 99999 for v in vm] print p 

Output:

 [99999, 99999, 99999, 99999, 0, 1, 2, 0] [99999, 99999, 99999, 99999, 0, 1, 2, 0] 

Instead of using append() in understanding the list, you can refer to p as direct output and use q.index(v) and 99999 in LC.

Not sure if this is intentional, but note that q.index(v) will only find the first occurrence of v , even if you have several in q . If you want to get the index of all v in q , consider using an enumerator and a list of indexes already visited

Something in these lines (pseudo-code):

 visited = [] for i, v in enumerator(vm): if i not in visited: p.append(q.index(v)) else: p.append(q.index(v,max(visited))) # this line should only check for v in q after the index of max(visited) visited.append(i) 
+1
source share

All Articles