#python #arrays #function #loops
#python #массивы #функция #циклы
Вопрос:
Я пытаюсь создать функцию, которая распространяет слух из одного пикселя на другие соседние пиксели, если они == 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
Ответ №1:
Есть несколько циклов, которые вы могли бы применить для достижения чего-то подобного. Во-первых, 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
Выше мы выбираем 7 случайных букв из строки abcdefghijk
и проверяем, составляют ли 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]
[]
Как вы можете видеть, каждый раз, когда условие не выполняется, мы передаем обновленный параметр обратно в начало цикла. В этом примере вы можете видеть, что каждый раз, когда возникает цикл, он удаляет последний элемент из списка и возвращает его в начало.