Inline for loop

Ik probeer nette pythonische manieren te leren om dingen te doen, en vroeg me af waarom mijn for-lus niet op deze manier kan worden aangepast:

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

Ik heb geprobeerd de for-lus te vervangen door:

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

Maar het werkt niet. De for v in vm:-lus verwijdert nummers uit vmop basis van wanneer ze de volgende zijn in q.


Antwoord 1, autoriteit 100%

Wat u gebruikt, wordt een lijstbegripgenoemd in Python, geen inline for-loop (ook al lijkt het erop). Je zou je lus als een lijstbegrip als volgt schrijven:

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

Als je een lijstbegrip gebruikt, roep je list.appendniet aan omdat de lijst wordt opgebouwd uit het begrip zelf. Elk item in de lijst is wat wordt geretourneerd door de uitdrukking aan de linkerkant van het trefwoord for, in dit geval q.index(v) if v in q else 99999. Overigens, als je list.appendbinnen een begrip gebruikt, dan krijg je een lijst met Nonewaarden, want dat is wat de appendmethode is keert altijd terug.


Antwoord 2, autoriteit 7%

uw lijstcomphresnion zal werken, maar zal de lijst van None retourneren omdat 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]

betere manier om het als volgt te gebruiken:

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

Antwoord 3, autoriteit 4%

je kunt enumerategebruiken om de ind/index van de elementen te behouden is in vm, als je vmeen setu zult ook 0(1)zoekacties hebben:

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

Antwoord 4

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

Uitvoer:

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

In plaats van append()in het lijstbegrip te gebruiken, kunt u verwijzen naar de p als directe uitvoer, en q.index(v)en 99999in de LC.

Weet niet zeker of dit opzettelijk is, maar houd er rekening mee dat q.index(v)alleen de eerste keer dat vvoorkomt, zal vinden, ook al heb je er meerdere in q. Als je de index wilt krijgen van alle vin q, overweeg dan om een enumeratorte gebruiken en een lijst met reeds bezochte indexes

Iets in die regels (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)

Other episodes