lst = [1, 3, 2, 1, 3, True, False, True, "apple", "banana", "mango", "apple"]
lst2 = []
for i in range(0, len(lst)):
if lst[i] not in lst2:
lst2.append(lst[i])
print(lst2)
Above code is to remove duplicate values. But it is also removing True
value. Anyone Explain me why it's not storing True
value and show me correct code.
Desired Output:
[1,3,2, True, False, “apple”, “banana”, “mango”]
Output I'm getting:
[1,3,2, False, “apple”, “banana”, “mango”]
Can anyone help me with this and explain me reason behind it. Please it would be really helpful.
CodePudding user response:
In Python True
is considered equivalent to 1
for the purposes of equality checks and mathematical operations, even though they have different types (bool
vs int
).
If you want to compare them as being different, a workaround might be to convert each value into a tuple with its type (because even though 1 == True
, (1, int) != (True, bool)
) for purposes of the comparison, and then convert them back when you're done:
>>> lst = [1, 3, 2, 1, 3, True, False, True, "apple", "banana", "mango", "apple"]
>>> for i in lst:
... if (i, type(i)) not in lst2:
... lst2.append((i, type(i)))
...
>>> lst2 = [i for i, _ in lst2]
>>> lst2
[1, 3, 2, True, False, 'apple', 'banana', 'mango']
If you don't care about the order, you can do this more easily with a set
:
>>> [i for i, _ in {(i, type(i)) for i in lst}]
[True, 2, 3, 'mango', False, 'banana', 1, 'apple']
or if you do care about the order but still want to do it in a comprehension, you can do a bit of trickery with a dict
(since dict keys are unique but unlike a set they preserve insertion order):
>>> [i for i, _ in {(i, type(i)): None for i in lst}]
[1, 3, 2, True, False, 'apple', 'banana', 'mango']
CodePudding user response:
You can use this code.
lst = [1, 3, 2, 1, 3, True, False, True, "apple", "banana", "mango", "apple"]
lst2 = []
for a in lst:
if not any(a is i for i in lst2):
lst2.append(a)
print(lst2)
OUTPUT [1, 3, 2, True, False, 'apple', 'banana', 'mango']
CodePudding user response:
Like @Samwise said, when python compares booleans it actually sets them to integers: True == 1
and False == 0
.
You can try to process them separatly like this:
lst = [1, 3, 2, 1, 3, True, False, True, "apple", "banana", "mango", "apple"]
lst_bools = list(set([i for i in lst if type(i) == bool]))
lst_not_bool = list(set([i for i in lst if type(i) != bool]))
lst2 = lst_bools lst_not_bool
CodePudding user response:
This appears to work and also retain the list order.
lst = [1, 3, 2, 1, 3, True, False, True, "apple", "banana", "mango", "apple"]
s = set((e, type(e)) for e in lst)
newlist = []
for e in lst:
if (t := (e, type(e))) in s:
newlist.append(t[0])
s.remove(t)
print(newlist)
Output:
[1, 3, 2, True, False, 'apple', 'banana', 'mango']