Skip to content

Issue 796 resolved #919

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Sep 17, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 89 additions & 8 deletions docs/writing/style.rst
Original file line number Diff line number Diff line change
Expand Up @@ -581,43 +581,124 @@ provide a powerful, concise way to work with lists. Also, the :py:func:`map` and
:py:func:`filter` functions can perform operations on lists using a different,
more concise syntax.

Filtering a list
~~~~~~~~~~~~~~~~

**Bad**:

Never remove items from a list while you are iterating through it.

.. code-block:: python

# Filter elements greater than 4
a = [3, 4, 5]
b = []
for i in a:
if i > 4:
b.append(i)
a.remove(i)

Don't make multiple passes through the list.

.. code-block:: python

while i in a:
a.remove(i)

**Good**:

Python has a few standard ways of filtering lists.
The approach you use depends on

* Python 2.x vs. 3.x
* Lists vs. iterators
* Possible side effects of modifying the original list

Python 2.x vs. 3.x
::::::::::::::::::

Starting with Python 3.0, the :py:func:`filter` function returns an iterator instead of a list.
Wrap it in :py:func:`list` if you truly need a list.

.. code-block:: python

a = [3, 4, 5]
b = [i for i in a if i > 4]
# Or:
b = filter(lambda x: x > 4, a)
list(filter(...))

List comprehensions and generator expressions work the same in both 2.x and 3.x (except that comprehensions in 2.x "leak" variables into the enclosing namespace)

* comprehensions create a new list object
* generators iterate over the original list

The :py:func:`filter` function

* in 2.x returns a list (use itertools.ifilter if you want an iterator)
* in 3.x returns an iterator

Lists vs. iterators
:::::::::::::::::::

Creating a new list requires more work and uses more memory. If you a just going to loop through the new list, consider using an iterator instead.

.. code-block:: python

# comprehensions create a new list object
filtered_values = [value for value in sequence if value != x]
# Or (2.x)
filtered_values = filter(lambda i: i != x, sequence)

# generators don't create another list
filtered_values = (value for value in sequence if value != x)
# Or (3.x)
filtered_values = filter(lambda i: i != x, sequence)
# Or (2.x)
filtered_values = itertools.ifilter(lambda i: i != x, sequence)



Possible side effects of modifying the original list
::::::::::::::::::::::::::::::::::::::::::::::::::::

Modifying the original list can be risky if there are other variables referencing it. But you can use *slice assignment* if you really want to do that.

.. code-block:: python

# replace the contents of the original list
sequence[::] = [value for value in sequence if value != x]
# Or
sequence[::] = (value for value in sequence if value != x)
# Or
sequence[::] = filter(lambda value: value != x, sequence)


Modifying the values in a list
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**Bad**:

Remember that assignment never creates a new object. If two or more variables refer to the same list, changing one of them changes them all.

.. code-block:: python

# Add three to all list members.
a = [3, 4, 5]
b = a # a and b refer to the same list object

for i in range(len(a)):
a[i] += 3
a[i] += 3 # b[i] also changes

**Good**:

It's safer to create a new list object and leave the original alone.

.. code-block:: python

a = [3, 4, 5]
b = a

# assign the variable "a" to a new list without changing "b"
a = [i + 3 for i in a]
# Or:
# Or (Python 2.x):
a = map(lambda i: i + 3, a)
# Or (Python 3.x)
a = list(map(lambda i: i + 3, a))


Use :py:func:`enumerate` keep a count of your place in the list.

Expand Down