From c582477e310def3882a9b6d60551758cea4c7dbb Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Thu, 24 Sep 2020 15:40:52 -0400 Subject: [PATCH 1/5] bpo-41774: Add programming FAQ entry In the "Sequences (Tuples/Lists)" section, add "How do you remove multiple items from a list". --- Doc/faq/programming.rst | 20 +++++++++++++++++++ .../2020-09-24-15-35-13.bpo-41774.5IqdGP.rst | 2 ++ 2 files changed, 22 insertions(+) create mode 100644 Misc/NEWS.d/next/Documentation/2020-09-24-15-35-13.bpo-41774.5IqdGP.rst diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index fd0adc378bfa6f..ea9a79cca0c703 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -1164,6 +1164,26 @@ This converts the list into a set, thereby removing duplicates, and then back into a list. +How do you remove multiple items from a list +-------------------------------------------- + +As with removing duplicates, iterating in reverse is one solution:: + + for i, item in range(len(mylist)-1, -1, -1): + if remove(item): + del mylist[i] + +For a long enough list with enough deletions, moving keep items to +the front of the list, using a second index, should be faster:: + + j = 0 + for i, item in enumerate(mylist): + if keep(item): + mylist[j] = item + j += 1 + del mylist[j:] + + How do you make an array in Python? ----------------------------------- diff --git a/Misc/NEWS.d/next/Documentation/2020-09-24-15-35-13.bpo-41774.5IqdGP.rst b/Misc/NEWS.d/next/Documentation/2020-09-24-15-35-13.bpo-41774.5IqdGP.rst new file mode 100644 index 00000000000000..af8e02437cb2b5 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2020-09-24-15-35-13.bpo-41774.5IqdGP.rst @@ -0,0 +1,2 @@ +In Programming FAQ "Sequences (Tuples/Lists)" section, add "How do you +remove multiple items from a list". From bee073d5352e054747c9fd38cacf63f193d26024 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Thu, 24 Sep 2020 15:59:50 -0400 Subject: [PATCH 2/5] Fix code with tested code. --- Doc/faq/programming.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index ea9a79cca0c703..c2210c852682a8 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -1169,9 +1169,10 @@ How do you remove multiple items from a list As with removing duplicates, iterating in reverse is one solution:: - for i, item in range(len(mylist)-1, -1, -1): - if remove(item): - del mylist[i] + for i in range(len(mylist)-1, -1, -1): + if remove(mylist[i]): + del mylist[i] + For a long enough list with enough deletions, moving keep items to the front of the list, using a second index, should be faster:: From eb5bb501ac35a9b3a24bee24f4cb309cbc9f5181 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Thu, 24 Sep 2020 16:16:10 -0400 Subject: [PATCH 3/5] Apply Eric's suggestions. --- Doc/faq/programming.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index c2210c852682a8..134de69daf24cb 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -1170,16 +1170,16 @@ How do you remove multiple items from a list As with removing duplicates, iterating in reverse is one solution:: for i in range(len(mylist)-1, -1, -1): - if remove(mylist[i]): + if should_remove(mylist[i]): del mylist[i] -For a long enough list with enough deletions, moving keep items to +For a long enough list with enough deletions, moving kept items to the front of the list, using a second index, should be faster:: j = 0 for i, item in enumerate(mylist): - if keep(item): + if should_keep(item): mylist[j] = item j += 1 del mylist[j:] From 9e96fe1fab8553ebb03b9a75b889b5a61cf406b5 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Thu, 24 Sep 2020 21:37:31 -0400 Subject: [PATCH 4/5] Use Raymond's idea, on the issue. --- Doc/faq/programming.rst | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index 134de69daf24cb..9b371b5c424efc 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -1167,22 +1167,18 @@ into a list. How do you remove multiple items from a list -------------------------------------------- -As with removing duplicates, iterating in reverse is one solution:: - - for i in range(len(mylist)-1, -1, -1): - if should_remove(mylist[i]): - del mylist[i] - - -For a long enough list with enough deletions, moving kept items to -the front of the list, using a second index, should be faster:: - - j = 0 - for i, item in enumerate(mylist): - if should_keep(item): - mylist[j] = item - j += 1 - del mylist[j:] +As with removing duplicates, explicitly iterating in reverse with a +delete condition is one possibility. However, using slice replacement +with an implicit or explicit forward iteration, depending on whether one +starts with a keep predicate function or keep condition, +is easier and less error-prone. For a long enough list with enough +deletions, this will also be faster. Here are the two options:: + + mylist[:] = filter(keep_function, mylist) + mylist[:] = (x for x in mylist if keep_condition) + +If space is not an issue, a list comprehension instead of a generator +comprehension may be faster. How do you make an array in Python? From 0c0cf158aa3e66cbdf0fa67348ba1358486231e4 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Mon, 28 Sep 2020 20:01:01 -0400 Subject: [PATCH 5/5] Condense text, include list comp. --- Doc/faq/programming.rst | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index 9b371b5c424efc..8b3be2a197af3a 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -1168,17 +1168,15 @@ How do you remove multiple items from a list -------------------------------------------- As with removing duplicates, explicitly iterating in reverse with a -delete condition is one possibility. However, using slice replacement -with an implicit or explicit forward iteration, depending on whether one -starts with a keep predicate function or keep condition, -is easier and less error-prone. For a long enough list with enough -deletions, this will also be faster. Here are the two options:: +delete condition is one possibility. However, it is easier and faster +to use slice replacement with an implicit or explicit forward iteration. +Here are three variations.:: mylist[:] = filter(keep_function, mylist) mylist[:] = (x for x in mylist if keep_condition) + mylist[:] = [x for x in mylist if keep_condition] -If space is not an issue, a list comprehension instead of a generator -comprehension may be faster. +If space is not an issue, the list comprehension may be fastest. How do you make an array in Python?