2014-12-10 2 views
6

Ich versuche ordentlich pythonic Möglichkeiten zu lernen, Dinge zu tun, und frage mich, warum meine for-Schleife kann nicht auf diese Weise Refactoring:Inline for-Schleife

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 

Ich habe versucht, mit der for-Schleife zu ersetzen:

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

Aber es funktioniert nicht. Die for v in vm: Schleife entfernt Nummern von vm basierend auf, wenn sie als nächstes in q kommen.

+0

Möglicherweise möchten Sie verwenden - 1 anstelle von 99999 für eine Markierung eines nicht vorhandenen Wertes (so würde es sogar für eine Liste mit 99999+ Elementen funktionieren) –

+0

Sie Listenkomprehension wird funktionieren, aber es wird Listen von Keine zurückgeben – Hackaholic

+0

Ich habe 99999 anstelle von -1 verwendet, weil später ich lief a max (p) und nicht vorhandene Werte müssen ausgewählt werden. – Will

Antwort

10

Was Sie verwenden, heißt list comprehension in Python, keine Inline-Schleife (obwohl es ähnlich ist). Sie würden Ihre Schleife als Liste Verständnis schreiben wie so:

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

Wenn eine Liste Verständnis verwenden, Sie list.append nicht nennen, weil die Liste aus dem Verständnis selbst errichtet. Jedes Element in der Liste ist das, was vom Ausdruck auf der linken Seite des Schlüsselwortes for zurückgegeben wird, in diesem Fall q.index(v) if v in q else 99999. Wenn Sie list.append innerhalb eines Verständnisses verwenden, erhalten Sie eine Liste der None Werte, weil die append Methode immer zurückgibt.

+0

Danke Mann, super!+ Internet zur Beantwortung in weniger als einer Minute. – Will

2

können Sie enumerate verwenden die ind/Index der Elemente halten in vm ist, wenn Sie vm ein set machen auch 0(1) Lookups haben Sie:

vm = {-1, -1, -1, -1} 

print([ind if q in vm else 9999 for ind,ele in enumerate(vm) ]) 
+0

Coole Phantasie Syntax, danke für das Teilen sieht sehr nützlich aus! – Will

2

Ihre Liste comphresnion wird, arbeiten aber Liste zurück None weil anfügen Rückkehr 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] 

besser zu nutzen es wie folgt:

>>> a= [ x for x in range(10) ] 
>>> a 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
1
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 

Ausgang:

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

Statt append() in der Liste Verständnis verwenden Sie die p als direkte Ausgabe verweisen können, und q.index(v) und 99999 im LC verwenden.

Nicht sicher, ob dies beabsichtigt ist, aber beachten Sie, dass q.index(v) nur das erste Vorkommen von v finden wird, auch wenn Sie mehrere in q haben. Wenn Sie den Index aller v in q erhalten möchten, verwenden Sie ein enumerator und eine Liste der bereits indexes

besuchte

Etwas in diese Richtung (Pseudocode):

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)