我正试图创建一个函数,将谣言从一个像素传播到其他相邻像素,只要它们==1(而不是0(。我认为我现在拥有的函数可以一次将其扩展到相邻的像素,但我希望它每次都使用像素图的更新版本一次又一次地循环。当不满足某些条件时,我如何才能让它循环回到顶部?
def spread_rumor(array):
new_array = np.zeros_like(array) #make a copy of your city
for i in range(array.shape[0]): #for each index i for the number of rows:
for j in range(array.shape[1]): #for each index j for the number of columns
if array[i,j] == 0:
new_array[i,j] = 0
elif array[i,j] == 2:
new_array[i,j] = 2
elif array[i,j] == 1: #if the value of the city/board at [i,j] is a 1:
new_array[i,j] = 1 #we only do something if we find a person who can learn the rumor
neighbors = getNeighborValues(i,j, array) #get all of the values of their neighborhood cells
if np.any(np.array(neighbors) == 2) == True:
new_array[i,j] = 2
## there is more than one way to do this!
## You could use a loop to check all the neighbors and move one once you find one
## or you could check to see if there is a 2 in any of the neighbors
frac_empty = np.count_nonzero(array == 0)/array.size
frac_house = np.count_nonzero(array == 1)/array.size
frac_rumor = np.count_nonzero(array == 2)/array.size
if frac_empty + frac_rumor == 1.0: #the copy of our city is the same as city:
##our simulation isn't changing anymore,
##so making a copy and updating it isn't going to
##lead to further changes
spread_rumor = False
else:
##there are still changes going on
#this is where I would want it to start back over at the top again
return showCity(new_array) #this function creates a plt.imshow representation of the resulting array
可以应用一些循环来实现这样的功能。首先,一个while
循环。正如您所知,while
循环一直运行到满足条件为止。如果有许多条件,while
语句可能会变得非常难看。如果有许多条件,许多人会选择使用while True
。使用break
将退出循环。
def rand_string():
while True:
string = "".join(random.sample("abcdefghijk", 7))
if string == "afedgcb":
break
elif string == "cdefgab":
break
elif string == "gbadcef":
break
else:
continue
return string
上面,我们从字符串abcdefghijk
中随机选择7个字母,并检查这7个随机字母是否构成afedgcb
、cdefgab
或gbadcef
。如果是这样的话,我们中断循环并返回字符串。如果没有,我们将重新启动循环。else/continue
是不必要的,如果不满足任何条件,循环仍然会重新开始,因为我们没有突破循环。
另一种选择是递归。下面的例子简单地从0到10中选择一个随机数,并检查它是否等于5。如果是,我们返回数字。如果没有,我们只需再次运行该函数。
def rand_num_recursion():
num = random.randint(0,10)
if num == 5:
return num
else:
return rec()
现在,如果你是print(rec())
,答案总是5。为什么?因为函数将继续运行,直到选择的随机数为5。这个递归函数也可以很容易地转换为while
循环:
def rand_num_while():
num = random.randint(0,10)
while num != 5:
num = random.randint(0,10)
return num
如果你有参数怎么办
使用递归可以很容易地做到这一点。当然,下面的例子只是为了演示的目的——你永远不需要一个函数来";"空";一个列表,它只是如何将更新的参数传递回循环开始的一个示例。
def empty_list(lst):
if len(lst) == 0:
return lst
else:
print(lst)
return empty_list(lst[:-1]) # return all members of the list except for the last one
当您写入print(empty_list([1,2,3,4,5,6]))
并将print(lst)
保留在函数中时,输出如下:
[1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5]
[1, 2, 3, 4]
[1, 2, 3]
[1, 2]
[1]
[]
正如您所看到的,每次不满足条件时,我们都会将更新后的参数传递回循环的开头。在本例中,您可以看到,每次循环发生时,它都会从列表中删除最后一个元素,并将其传递回开头。