# “yield” Keyword in Python: Creating Generators

The `yield` keyword is a powerful tool for creating generators in Python. A generator is a function that returns an iterator, which allows you to iterate over a sequence of values without having to generate them all at once. This can be especially useful when working with large data sets or when you need to generate an infinite sequence of values.

In this tutorial, we’ll explore the `yield` keyword and how it can be used to create generators in Python. We’ll start with a simple example and then gradually build up to more complex examples.

## Example 1: A Basic Generator Function

Let’s start with a simple example that demonstrates the basic usage of the `yield` keyword:

```def my_generator():
yield 1
yield 2
yield 3

gen = my_generator()
print(next(gen)) # Output: 1
print(next(gen)) # Output: 2
print(next(gen)) # Output: 3```

In this example, we’ve defined a generator function `my_generator()` that yields the values 1, 2, and 3. We create an instance of this generator and assign it to the variable `gen`. We can then use the `next()` built-in function to retrieve each value from the generator one at a time.

The output of this example will be:

```1
2
3```

As you can see, each value is generated and returned one at a time as we call `next()` on the generator.

## Example 2: Using a Generator Function with a Loop

Now let’s look at how we can use a generator function within a loop to generate a sequence of values:

```def countdown(num):
print('Starting')
while num > 0:
yield num
num -= 1

for i in countdown(5):
print(i)```

In this example, `countdown()` is a generator function that yields a sequence of numbers from the value passed in as an argument down to 1. We can use this generator within a for loop, which will automatically call `next()` on the generator to retrieve each value.

The output of this example will be:

```Starting
5
4
3
2
1```

You can see that the `countdown()` function is called only once, when the generator is created. The loop then retrieves each value from the generator one at a time until the sequence is exhausted.

## Example 3: Using the Send() Method with Generators

Another powerful feature of generators is the ability to pass data back into the generator with the `send()` method. Let’s look at an example:

```def echo():
while True:

e = echo()
next(e) # Required to start the generator
e.send('Hello!') # Output: You said: Hello!
e.send('How are you?') # Output: You said: How are you?```

In this example, we’ve defined a generator function `echo()` that receives data with the `yield` keyword and then prints it out. We create an instance of this generator and assign it to the variable `e`. We use `next()` to start the generator and then use `send()` to pass data back into it.

The output of this example will be:

```You said: Hello!
You said: How are you?```

As you can see, the `echo()` function is called repeatedly with different values passed in each time using the `send()` method.

## Conclusion

The `yield` keyword is a powerful tool for creating generators in Python. Generators can be used to generate a sequence of values one at a time, which can be a huge improvement in efficiency when working with very large datasets or infinite sequences. By using `yield`, you can create generators that are both powerful and efficient, making your code more elegant and easier to maintain.