diff --git a/notes-en/python-iterators.md b/notes-en/python-iterators.md
new file mode 100644
index 0000000..b10c835
--- /dev/null
+++ b/notes-en/python-iterators.md
@@ -0,0 +1,97 @@
+# About iterators and iterables
+
+## How to create your own iterator or iterable?
+
+In Python we have two complementary terms: iterator and iterable.
+
+An **iterable** is an object that has an `__iter__` method which returns an iterator, or which defines a `__getitem__` method that can take sequential indexes starting from zero (and raises an IndexError when the indexes are no longer valid). So an iterable is an object that you can get an iterator from. By default `__iter__` always returns `self`.
+
+An **iterator** is an object with a `__next__` method.
+
+
+## How to get iterator from iterable?
+
+You can get iterator from any iterable via `iter` function:
+
+```python
+In [1]: i = iter([1, 2])
+
+In [2]: i
+Out[2]:
+```
+
+You can iterate it manually via `next` function:
+
+```python
+In [3]: next(i)
+Out[3]: 1
+
+In [4]: next(i)
+Out[4]: 2
+
+In [5]: next(i)
+StopIteration:
+```
+
+Many functions, like `map`, `functools.reduce`, `itertools.product` etc, returns iterator:
+
+```python
+In [14]: m = map(str, range(3))
+
+In [15]: next(m)
+Out[15]: '0'
+
+In [16]: m
+Out[16]: