You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/writing/style.rst
+89-8Lines changed: 89 additions & 8 deletions
Original file line number
Diff line number
Diff line change
@@ -581,43 +581,124 @@ provide a powerful, concise way to work with lists. Also, the :py:func:`map` and
581
581
:py:func:`filter` functions can perform operations on lists using a different,
582
582
more concise syntax.
583
583
584
+
Filtering a list
585
+
~~~~~~~~~~~~~~~~
586
+
584
587
**Bad**:
585
588
589
+
Never remove items from a list while you are iterating through it.
590
+
586
591
.. code-block:: python
587
592
588
593
# Filter elements greater than 4
589
594
a = [3, 4, 5]
590
-
b = []
591
595
for i in a:
592
596
if i >4:
593
-
b.append(i)
597
+
a.remove(i)
598
+
599
+
Don't make multiple passes through the list.
600
+
601
+
.. code-block:: python
602
+
603
+
while i in a:
604
+
a.remove(i)
594
605
595
606
**Good**:
596
607
608
+
Python has a few standard ways of filtering lists.
609
+
The approach you use depends on
610
+
611
+
* Python 2.x vs. 3.x
612
+
* Lists vs. iterators
613
+
* Possible side effects of modifying the original list
614
+
615
+
Python 2.x vs. 3.x
616
+
::::::::::::::::::
617
+
618
+
Starting with Python 3.0, the :py:func:`filter` function returns an iterator instead of a list.
619
+
Wrap it in :py:func:`list` if you truly need a list.
620
+
597
621
.. code-block:: python
598
622
599
-
a = [3, 4, 5]
600
-
b = [i for i in a if i >4]
601
-
# Or:
602
-
b =filter(lambdax: x >4, a)
623
+
list(filter(...))
624
+
625
+
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)
626
+
627
+
* comprehensions create a new list object
628
+
* generators iterate over the original list
629
+
630
+
The :py:func:`filter` function
631
+
632
+
* in 2.x returns a list (use itertools.ifilter if you want an iterator)
633
+
* in 3.x returns an iterator
634
+
635
+
Lists vs. iterators
636
+
:::::::::::::::::::
603
637
638
+
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.
639
+
640
+
.. code-block:: python
641
+
642
+
# comprehensions create a new list object
643
+
filtered_values = [value for value in sequence if value != x]
644
+
# Or (2.x)
645
+
filtered_values =filter(lambdai: i != x, sequence)
646
+
647
+
# generators don't create another list
648
+
filtered_values = (value for value in sequence if value != x)
649
+
# Or (3.x)
650
+
filtered_values =filter(lambdai: i != x, sequence)
651
+
# Or (2.x)
652
+
filtered_values = itertools.ifilter(lambdai: i != x, sequence)
653
+
654
+
655
+
656
+
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.
660
+
661
+
.. code-block:: python
662
+
663
+
# replace the contents of the original list
664
+
sequence[::] = [value for value in sequence if value != x]
665
+
# Or
666
+
sequence[::] = (value for value in sequence if value != x)
667
+
# Or
668
+
sequence[::] =filter(lambdavalue: value != x, sequence)
669
+
670
+
671
+
Modifying the values in a list
672
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
604
673
**Bad**:
605
674
675
+
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.
676
+
606
677
.. code-block:: python
607
678
608
679
# Add three to all list members.
609
680
a = [3, 4, 5]
681
+
b = a # a and b refer to the same list object
682
+
610
683
for i inrange(len(a)):
611
-
a[i] +=3
684
+
a[i] +=3# b[i] also changes
612
685
613
686
**Good**:
614
687
688
+
It's safer to create a new list object and leave the original alone.
689
+
615
690
.. code-block:: python
616
691
617
692
a = [3, 4, 5]
693
+
b = a
694
+
695
+
# assign the variable "a" to a new list without changing "b"
618
696
a = [i +3for i in a]
619
-
# Or:
697
+
# Or (Python 2.x):
620
698
a =map(lambdai: i +3, a)
699
+
# Or (Python 3.x)
700
+
a =list(map(lambdai: i +3, a))
701
+
621
702
622
703
Use :py:func:`enumerate` keep a count of your place in the list.
0 commit comments