简体   繁体   中英

Python calls the same function in a loop, and uses the return value of the last call as the parameter of this call

This is kmeans I wrote. I want to call this function cyclically to repeatedly calculate the distance to the center point and enter the return as parameter the first input is (b[0,:],b[1,:])

def DIV(point1,point2):   
    plt.figure()
    c = []
    d = []
    for i in range(1000):
        dist1 = np.linalg.norm(Z[i] - point1)
        dist2 = np.linalg.norm(Z[i] - point2)
        if dist1 > dist2:
            c.append(Z[i])
        else:
            d.append(Z[i])
    C = np.array(c)
    D = np.array(d)
    plt.scatter(C[:,0],C[:,1],s=16.,color='green')
    plt.scatter(D[:,0],D[:,1],s=16.,color='yellow')

    center1 = C.mean(axis=0)
    center2 = D.mean(axis=0)
    plt.scatter(center1[0],center1[1],marker ='x',s=16.,color='red')
    plt.scatter(center2[0],center2[1],marker ='x',s=16.,color='red')
    return center1,center2

Your function and background don't matter much, sounds like you are basically trying to do a "fixed point" function based on your response to my comment:

def fix(func, initial, max_iter):
    prev = func(initial)
    iteration = 1
    while True:
        curr = func(prev)
        if curr == prev or iteration > max_iter:
            break
        prev = curr
        iteration += 1
    return curr

For your specific case, you could then write

div = lambda (a, b): DIV(a, b)
result = fix(div, (b[0,:],b[1,:]), max_iter=1000)

if you wanted to use the same logic inline, instead of using more generic logic, you could write

prev = DIV(b[0,:],b[1,:])
iteration = 1
while True:
    curr = DIV(*prev)
    if curr == prev or iteration > 1000:
        break
    prev = curr
    iteration += 1
result = curr

I used very cumbersome loops and functions to control its iteration

    def paste(head, start=0, stop=0, step=1, sep=''):
        return [f'{head}{sep}{i}' for i in range(start, stop, step)]
   def loop(n):
        k = paste('a', 0, n)
        k[0],k[1] = DIV(b[0,:],b[1,:])
        for i in range(0,n,2):
            k[i],k[i+1] = DIV(k[i],k[i+1])
            for j in range(2,n,2):            
                k[j],k[j+1] = DIV(k[i],k[i+1])

    loop(6)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM