Je travaille avec des générateurs en Python, et je reçois un comportement étrange. Je ne suis pas entièrement comment formuler la question ...Odd Python zip() comportement
Mon code effectue une recherche de motif sur une fonction d'objectif. Le problème que je vois apparaît quand je zip
les résultats de mon générateur patternSearch
avec un xrange
pour obtenir seulement les 12 premiers résultats. Il semble que le composant xmin
du tuple retourné par mon générateur soit répété sur toute la longueur du zip. Ce qui est particulièrement bizarre, le composant ymin
du même tuple n'est pas répété. Lorsque j'initialise un objet générateur ps
et appelez ps.next()
à plusieurs reprises, les résultats sont corrects.
Quel pourrait être le problème? Merci!
code
#!/usr/bin/env python2.7
def obj(x):
x1,x2 = x
return 100*(x2 - x1**2)**2 + (1 - x1)**2
# fobj: objective function of vector x
# x0: initial point
# h: initial step size
# r: reduction parameter
def patternSearch(fobj,x0,h,r):
n = len(x0) # get dimensionality
dims = range(0,n)
# initialize given x0
xmin = list(x0)
ymin = fobj(xmin)
yield (xmin,ymin) # send back the initial condition first
while True:
focus = True
for i in dims:
x = xmin # start from the last best point
x[i] += h
y = fobj(x) # eval
if y < ymin:
ymin = y
xmin = x
focus = False
continue
# else, y > ymin
x[i] -= 2*h # go in the opposite direction
y = fobj(x) # eval
if y < ymin:
ymin = y
xmin = x
focus = False
continue
# else, no update to this dim
if focus:
h *= r
yield (xmin,ymin)
def main():
x0 = (3,5)
imax = 12
print 'Initial condition: ', x0
print 'Stop condition: i == ', imax
print 'Iteration | x1 | x2 | y '
for (x,y), i in zip(patternSearch(obj,x0,h=0.5,r=0.5), xrange(imax)):
print "{:>9} | {:<10} | {:<10} | {:<11}".format(i,x[0],x[1],y)
print 'Generator output test:'
g = patternSearch(obj,x0,0.5,0.5)
for i in xrange(imax):
g.next()
Sortie
Initial condition: (3, 5)
Stop condition: i == 12
Iteration | x1 | x2 | y
0 | 2.0 | 4.03125 | 1604
1 | 2.0 | 4.03125 | 58.5
2 | 2.0 | 4.03125 | 58.5
3 | 2.0 | 4.03125 | 1.953125
4 | 2.0 | 4.03125 | 1.953125
5 | 2.0 | 4.03125 | 1.2900390625
6 | 2.0 | 4.03125 | 1.2900390625
7 | 2.0 | 4.03125 | 1.13043212891
8 | 2.0 | 4.03125 | 1.13043212891
9 | 2.0 | 4.03125 | 1.06357192993
10 | 2.0 | 4.03125 | 1.06357192993
11 | 2.0 | 4.03125 | 1.03150010109
Generator output test:
([3, 5], 1604)
([2.5, 5.5], 58.5)
([2.0, 5.0], 58.5)
([2.25, 4.75], 1.953125)
([2.0, 4.5], 1.953125)
([2.125, 4.375], 1.2900390625)
([2.0, 4.25], 1.2900390625)
([2.0625, 4.1875], 1.13043212890625)
([2.0, 4.125], 1.13043212890625)
([2.03125, 4.09375], 1.0635719299316406)
([2.0, 4.0625], 1.0635719299316406)
([2.015625, 4.046875], 1.0315001010894775)
"*' zip' les résultats de mon 'générateur de patternSearch' avec un' xrange' *" - pas d'amour pour' enumerate'? –
Je pensais que c'était un moyen plus facile de se terminer que 'si i> imax: break' – abatea