web-dev-qa-db-fra.com

En ligne pour la boucle

J'essaie d'apprendre des façons pythoniques de faire les choses, et je me demandais pourquoi ma boucle for ne pouvait pas être refactorisée de cette façon:

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

J'ai essayé de remplacer la boucle for par:

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

Mais ça ne marche pas. Le for v in vm: loop expulse les nombres de vm en fonction de leur prochaine date dans q.

13
Will

Ce que vous utilisez s'appelle un compréhension de la liste en Python, pas une boucle for inline (même s'il est similaire à un). Vous écririez votre boucle comme une compréhension de liste comme ceci:

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

Lorsque vous utilisez une compréhension de liste, vous n'appelez pas list.append Car la liste est construite à partir de la compréhension elle-même. Chaque élément de la liste sera ce qui est retourné par l'expression à gauche du mot clé for, qui dans ce cas est q.index(v) if v in q else 99999. Par ailleurs, si vous utilisez list.append Dans une compréhension, vous obtiendrez une liste de valeurs None car c'est ce que la méthode append renvoie toujours.

33
iCodez

vous pouvez utiliser énumérer en gardant l'ind/l'index des éléments dans vm, si vous faites vm a set vous aurez également 0(1) recherches:

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

print([ind if q in vm else 9999 for ind,ele in enumerate(vm) ])
2
Padraic Cunningham

votre comphresnion de liste fonctionnera, mais renverra la liste de None parce que l'ajout retourne None:

démo:

>>> 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]

meilleure façon de l'utiliser comme ceci:

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

Sortie:

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

Au lieu d'utiliser append() dans la compréhension de la liste, vous pouvez référencer le p comme sortie directe et utiliser q.index(v) et 99999 Dans le LC.

Je ne sais pas si c'est intentionnel mais notez que q.index(v) ne trouvera que la première occurrence de v, même si vous en avez plusieurs dans q. Si vous voulez obtenir l'index de tous les v dans q, pensez à utiliser un enumerator et une liste des indexes déjà visités

Quelque chose dans ces lignes (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
f.rodrigues