Reputation: 13
Basically I'm trying to search a list from a list (not sure if they are actually lists or dictionary, but I've included the exact input) and if item from list 1 is not in list 2 I want to remove it from list 1, what ever I do all I get is what's in the list and not what's not in the list.
import datetime
listone = {}
listtwo = []
listone["https://www.somesite.com.au/1"]= datetime.datetime.now()
listone["https://www.somesite.com.au/2"]= datetime.datetime.now()
listone["https://www.somesite.com.au/3"]= datetime.datetime.now()
listtwo.append(["http://www.not.com/not1","test 1"])
listtwo.append(["http://www.not.com/not2","test 6"])
listtwo.append(["http://www.not.com/not3","test 5"])
listtwo.append(["http://www.not.com/not4","test 4"])
listtwo.append(["http://www.not.com/not5","test 3"])
listtwo.append(["http://www.not.com/not6","test 2"])
listtwo.append(["https://www.somesite.com.au/2", "test 1"])
temp = listone.copy()
for key, value in temp.items():
for item in listtwo:
if item[0] != key:
listone.pop(item[0], None)
print(listone)
Now I'm only getting back somesite 1 and 3 in listone after the code has ran, which it should be somesite 2 in listone and 1 and 3 should be removed. Can someone point out where I'm going wrong please?
Upvotes: 1
Views: 105
Reputation: 236014
You need to test if an element is not in the whole list of filtered elements before deciding to remove it. There's a simpler solution: first, extract the items that you want to use for filtering. I'll use a set
for efficiency and a generator expression for extracting the URLs:
urls = set(url for url, text in listtwo)
Then, create a new dictionary without the elements that you want to filter; here I'm using a dictionary comprehension:
listone = {k: v for k, v in listone.items() if k in urls}
The result will be as expected:
listone
=> {'https://www.somesite.com.au/2': datetime.datetime(2021, 4, 15, 13, 38, 20, 388197)}
By the way, listone
is actually a dictionary, not a list.
Upvotes: 1
Reputation: 14226
It sounds like you don't quite understand the logic you wrote. In your first iteration of the loop, key
is equal to https://www.somesite.com.au/1
. The nested loop, for item in listtwo
will then have item[0]
try to pop
a value from temp
if it does not match https://www.somesite.com.au/1
. In that first iteration none of the values of item[0]
will match so your if
statement is met for every iteration of the loop. None of the values of item[0]
are in temp
besides the last one, "https://www.somesite.com.au/2"
. Therefore, when you reach the final iteration of the loop it will remove that value from temp
.
If we modify the code to print
what it plans to pop
and what it actually removes you can see what I describe happen.
Going to try to pop -> http://www.not.com/not1
Actually popped -> None
Going to try to pop -> http://www.not.com/not2
Actually popped -> None
Going to try to pop -> http://www.not.com/not3
Actually popped -> None
Going to try to pop -> http://www.not.com/not4
Actually popped -> None
Going to try to pop -> http://www.not.com/not5
Actually popped -> None
Going to try to pop -> http://www.not.com/not6
Actually popped -> None
Going to try to pop -> https://www.somesite.com.au/2
Actually popped -> 2021-04-15 07:50:10.448479
....
That is the reason your code is not working as expected.
Upvotes: 0