как уменьшить цикл - PullRequest
       1

как уменьшить цикл

0 голосов
/ 24 февраля 2020

Мне интересно, есть ли какой-нибудь возможный способ уменьшить l oop в python? Я искал на многих сайтах, но не нашел ничего полезного. Например, я думал об этой простой функции:

def fun():
    colors = ["red", "grn", "blu", "prpl"]
    i = 0
    while 4 > i >= 0:
        for i, r in enumerate(colors):
            us = input("Enter your color\n")
            if us == 'red':
                i += 1
                print("r:", r)
            else:
                print("sorry, no", us, "enter the color again")
                i -= 1

Если входное значение равно 'red', увеличьте i, иначе уменьшите его. Затем я заметил, что in / decment никак не влияет на i. Как я могу уменьшить i, если ввод не был 'red'?

РЕДАКТИРОВАТЬ: Извините, мой вопрос не был ясен. Программа выполняет итерацию списка colors, когда us не равен red, программа должна уменьшить значение i. Ниже приведена желаемая выходная выборка. Надеюсь, теперь все ясно.

Желаемая выходная выборка:

Enter your color
red
r: red

Enter your color
red
r: grn

Enter your color
r
sorry, no r enter the color again
Enter your color
red
r: grn

1 Ответ

0 голосов
/ 24 февраля 2020

Кстати, ваш код в вопросе это обновление i. Но i просто переназначается текущее значение, генерируемое перечислителем на каждой итерации.

...     i = 0
...     while 4 > i >= 0:
...         for i, r in enumerate(colors):

Давайте сосредоточимся на двух циклах, которые есть в вашем коде. Внешний while l oop выглядит хорошо. У вас есть диапазон значений, которые вы хотите, чтобы i оставался в пределах, чтобы продолжить цикл. Отлично.

Во внутреннем l oop вы используете enumerate() для создания генератора, который производит последовательность кортежей: (0, 'red'), (1, 'grn'), (2, 'blu'), (3, 'prpl') И в том же выражении вы присваиваете i с помощью число c значение в каждом кортеже и r с цветом.

Каждый раз, когда через l oop, i является значением от 0 до 3, а 'r' является цветом ( который никогда не используется ни для чего). Значения i и r будут установлены для следующего кортежа в списке на каждой итерации независимо от того, что вы назначаете им в l oop.

Возможно, вы действительно избавитесь от внутреннего за l oop, и ваша программа все равно будет работать. Без внутреннего l oop вы будете просто l oop, пока i не выйдет за пределы диапазона.

Однако, поскольку у вас есть внутренний l oop, ваше число итераций умножается на количество кортежей enumerate() производит. Так, скажем, внешний l oop циклически проходит 4 раза, поскольку из-за этого внутреннего l oop вам придется ответить на входной вопрос 4 (внешний) * 4 (внутренний) = 16 раз.

Вам следует подумать о переопределении только с одним l oop - без внутреннего.

Итак, вопрос гласит: «Как вы уменьшите l oop в python». Сделайте это, если вы хотите считать в обратном направлении - или используйте некоторое время l oop, чтобы иметь больше контроля над i:

>>> for i in range(10, 0, -1):
...     print(i)

Так, согласно ветке комментариев, for l oop в Python вызывает итерацию по значениям, указанным в операторе for в указанном предсказуемом порядке.

Если вы хотите, чтобы i перебирал целочисленные значения от 1 до 100, но увеличивался на 2 каждый раз через l oop, вы можете закодировать его как:

for i in range(1, 100, 2):

Если, однако, вы хотите, чтобы i отличался по-разному в зависимости от кода в l oop, это было бы более уместно:

i = 0
while i < 20:
    i += 1
    ri = random.randint(0 , 5)
    if ri == 2:
        i += 2
    elif ri == 3:
        i -= 1
    elif ri = 0:
        break;

Таким образом, переменная i легко обновляется динамически с помощью кода в l oop. Синтаксис просто отличается от C в этом случае. Вы также можете заставить Python l oop выйти из l oop, используя break, как в C - так что это один из способов изменить последовательность после ее запуска.

поскольку l oop полагается на генератор или итератор, чтобы дать ему новый элемент (или элементы), который он может назначать для al oop var (или vars) каждый раз через l oop. Находясь в движении, генератор или итератор передает каждый последовательный элемент, который был сконфигурирован / закодирован для производства. Вы не можете восстановить его или изменить величину, которую он увеличивает после запуска l oop. Вы преданы.

Хороший пример объекта генератора - range(0, 10, 2). Это на самом деле не генератор - он возвращает генератор в начале цикла. И for l oop запрашивает этот генератор для каждого следующего значения, пока оно не достигнет своего предела.

И хороший пример итератора:

>>> for foo in ['the', 'quick', 'fox']:
...     print(foo)

Список не является итератором - он создается для списка неявно. Этот итератор будет производить каждый элемент в списке в указанном порядке до тех пор, пока у него не закончится количество элементов.

Так что, как я уже сказал, как только начинается выполнение для l oop, значения, через которые он проходит, в значительной степени предопределено ... до сегодняшнего дня .. =) Я должен прояснить это: следующий код только для развлечения. Не пишите такой код для своих проектов.

В l oop ниже variable_indices() создает генератор.

>>> import random
>>> variable_index = 0
>>>
>>> def variable_indices(min, max, step):
...     global variable_index
...     variable_index = min
... 
...     while variable_index >= min and variable_index < max:
...         variable_index += step
...         print(f"variable_indices() producing value: {variable_index}")
...         yield variable_index
...         
>>> for i in variable_indices(0, 10, 1):
... 
...     if random.randint(0, 2) == 2:
...         print("updating variable_index -= 1")
...         variable_index -= 1
...         
variable_indices() producing value: 1
variable_indices() producing value: 2
updating variable_index -= 1
variable_indices() producing value: 2
updating variable_index -= 1
variable_indices() producing value: 2
variable_indices() producing value: 3
variable_indices() producing value: 4
variable_indices() producing value: 5
updating variable_index -= 1
variable_indices() producing value: 5
variable_indices() producing value: 6
variable_indices() producing value: 7
updating variable_index -= 1
variable_indices() producing value: 7
variable_indices() producing value: 8
variable_indices() producing value: 9
variable_indices() producing value: 10

variable_indices должен, как и любой генератор, отображать значения в предсказуемой последовательности. Но в этом случае я сделал плохую вещь и сделал ее внутреннее состояние зависимым от глобальной переменной - которую я затем модифицирую в l oop. Полагаю, это могло бы продемонстрировать, что делать подобные вещи непросто, и поэтому не стоит =)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...