How do I move list elements to another list if a condition is met?
Question:
I have a list of values and I want to move certain (or all) values to another list if they exist in a reference list.
x = [2,3,4,5,6,7,8] # list of values
ref = [2,3,4,5,6,7,8] # reference list
result = [x.pop(i) for i, v in enumerate(x) if v in ref]
But because of popping the current index, it ends up giving every other value instead. Is there a nice straightforward way to do this?
What I want at the end of this example is x=[]
and result=[2,3,4,5,6,7,8]
, but ref
doesn’t need to contain all elements of x
, this was just for an example. In another case it might be:
x = [2,3,4,5,6,7,8] # list of values
ref = [2,6,7] # reference list
So then I want x = [3,4,5,8]
and result = [2,6,7]
Answers:
This works, but it’s a bit long.
x = [2,3,4,5,6,7,8] # list of values
ref = [2,3,4,5,6,7,8] # reference list
result = []
for i in x:
if i in ref:
result.append(i)
You could do it the old-fashioned way, with a while loop and a pointer into x
:
x = [2, 3, 4, 5, 6, 7, 8]
ref = [2, 6, 7]
result = []
i = 0
while i < len(x):
if x[i] in ref:
result.append(x.pop(i))
else:
i += 1
print(x)
print(result)
Output:
[]
[2, 3, 4, 5, 6, 7, 8]
You can simply iterate from the end to the start to avoid pop() changing the list size while iterating. Just call reverse() on your new list after running your loop if the order of the list matters.
In general, we should avoid modifying objects while iterating over them.
For this problem, we could generate result
and filter x
in two steps using comprehensions (avoiding appending to lists) as in the following example.
result, x = [v for v in x if v in ref], [v for v in x if v not in ref]
I have a list of values and I want to move certain (or all) values to another list if they exist in a reference list.
x = [2,3,4,5,6,7,8] # list of values
ref = [2,3,4,5,6,7,8] # reference list
result = [x.pop(i) for i, v in enumerate(x) if v in ref]
But because of popping the current index, it ends up giving every other value instead. Is there a nice straightforward way to do this?
What I want at the end of this example is x=[]
and result=[2,3,4,5,6,7,8]
, but ref
doesn’t need to contain all elements of x
, this was just for an example. In another case it might be:
x = [2,3,4,5,6,7,8] # list of values
ref = [2,6,7] # reference list
So then I want x = [3,4,5,8]
and result = [2,6,7]
This works, but it’s a bit long.
x = [2,3,4,5,6,7,8] # list of values
ref = [2,3,4,5,6,7,8] # reference list
result = []
for i in x:
if i in ref:
result.append(i)
You could do it the old-fashioned way, with a while loop and a pointer into x
:
x = [2, 3, 4, 5, 6, 7, 8]
ref = [2, 6, 7]
result = []
i = 0
while i < len(x):
if x[i] in ref:
result.append(x.pop(i))
else:
i += 1
print(x)
print(result)
Output:
[]
[2, 3, 4, 5, 6, 7, 8]
You can simply iterate from the end to the start to avoid pop() changing the list size while iterating. Just call reverse() on your new list after running your loop if the order of the list matters.
In general, we should avoid modifying objects while iterating over them.
For this problem, we could generate result
and filter x
in two steps using comprehensions (avoiding appending to lists) as in the following example.
result, x = [v for v in x if v in ref], [v for v in x if v not in ref]