Reputation: 11
I have a piece of code that I don't understand, I would appreciate it if someone could help me out.
list1 = [48, 33, 46, 46, 87, 11, 50, 99, 65, 87]
list2 = [48, 33, 46]
duplicates = [list1.pop(list1.index(i)) for i in list1 if i in list2]
Upvotes: 0
Views: 79
Reputation: 31574
I believe your code does not meet your requirements:
You want to find which elements in list1
are also in list2
. The result should be [48, 33, 46]
, but your result is [48, 46]
.
This is because after it finds 48
as a duplicate, 48
is deleted from list1
. During this process, the index of 33
changes from 1
to 0
. This means that the for
can not iterate over this element, as now it wants to iterate from index 1
. So 33
is missed.
The correct code is:
list1 = [48, 33, 46, 46, 87, 11, 50, 99, 65, 87]
list2 = [48, 33, 46]
# duplicates = [list1.pop(list1.index(i)) for i in list1 if i in list2]
duplicates = list(set([i for i in list1 if i in list2]))
print duplicates
And the main thing here is a python list comprehension.
Explain new code logic:
1. iterate 1st element of `list1` and find it in `list2`, so pick it. 2. repeat step 1 3. finally you get [48, 33, 46, 46], use `set` to change to [48, 33, 46], and use `list` to chanage back to list
Your old code logic:
1. iterate 1st element of `list1` and find it in `list2`, so pick it. 2. after pick it, you get the index of 1st element, then pop it (delete it from `list1` and return the element) so for this iterate, you get `48` 3. then you want to iterate 2rd element of `list1`, that supposed to be `33`; however, during the process of step2, you delete the `48`, so `33` becomes the 1st element, nolonger the 2rd element, so when you iterate, you missed the `33` & directly iterate to the `46` 4. for these not in `list2`, will not be handled.
Upvotes: 4
Reputation: 51335
Walk through it step by step, and it might make sense:
for i in list1 if i in list2
should make sense; it's the equivalent of
for i in list1:
if i in list2:
...
list1.index(i)
gets the index of i
(each element in list1
that is found in list2
), and finally list1.pop
removes the item at that index from list1
Upvotes: 1