+ 2

[1] in [[1]] - how can that be?

Usually a list with the same content would have a separate identity if it is not aliased. Yet there is a challenge that gives this as True, and shell confirms this. Can someone explain?

12th Oct 2018, 10:19 PM
HonFu
HonFu - avatar
9 Answers
+ 6
[1] is [1] --> False [1] == [1] --> True Their identities don't need to be the same, a weaker equality (==) is good enough for list membership testing. From the docs: "For container types such as list, tuple, set, frozenset, dict, or collections.deque, the expression x in y is equivalent to any(x is e or x == e for e in y)." https://docs.python.org/3.7/reference/expressions.html#membership-test-operations
13th Oct 2018, 4:04 AM
Kishalaya Saha
Kishalaya Saha - avatar
+ 4
That's true but in python the `==` operator compares lists element by element, unlike in other languages where you just get `false` if you compare any two arrays (unless both sides reference the same array as you said) I would guess `in` uses `==` behind the scenes and so `[1] in [[1]]` makes sense!
13th Oct 2018, 3:16 AM
Schindlabua
Schindlabua - avatar
+ 3
Warning: I don't know python Doesn't [1] in [[1]] means if [[1]] contains [1]. And [[1]] does contain [1] so it's true.
12th Oct 2018, 11:16 PM
qwerty
qwerty - avatar
+ 2
Python understand values between square brackets as a list. So, [1] is a list containing value 1, and [[1]] is a list containing a list containing value 1. So, [[1]] is a list with [1] as its only element.
13th Oct 2018, 1:30 AM
Emerson Prado
Emerson Prado - avatar
+ 2
Aaah, it is treated as '=='! Okay, then it makes sense ... thanks, Kish and Schindlabua! qwerty, in Python you can check, if it is the very same object in memory ('is') or if it is a similar list, but a different object ('=='). For simple data like an int or a string that normally doesn't matter, but with a container it can lead to problems, because if you think, you are deleting an element from a copy of a list but in reality it IS the list, then the element will disappear from the original list, too (because it's actually that list), and then you lose data without even knowing. In Python, when you write 'list2 = list1', list2 will not be a copy, but it will be an alias of list1, which is different to how it works for example in C. A lot of challenges are about this issue, so after a while you just expect it - but lately there are some new riddles where lists behave as one would expect - confusing! (lol)
13th Oct 2018, 7:16 AM
HonFu
HonFu - avatar
+ 1
Yeah, it's just how things are implemented. Can't be helped. So the clone of an element from the list is also in the list. Probably makes life easier in some situations.
13th Oct 2018, 7:37 AM
Kishalaya Saha
Kishalaya Saha - avatar
0
HonFu No, the 'in' operator does not act like '=='. Comparators, like '==', compare two values. The 'in' comparator compares the first operand with EACH ITEM from the second operand, which should be a list, set, dict, etc., and returns true if the first operand equals (now '==' comes in, but pls note the difference) AT LEAST ONE ITEM from the second operand. So, when you test '[1] in [[1]]', that's what happens: the second operand '[[1]]' is split in all its items - only '[1]' in this case. Then, the first operand '[1]' is compared to these items '[1]'. They're equal, so the operation returns true.
13th Oct 2018, 5:02 PM
Emerson Prado
Emerson Prado - avatar
0
Emerson Prado, isn't, what you're explaining, kind of obvious in the context of this thread? Everybody knows that we're talking of a list, not a single value, even my original question makes that quite clear. The point is that the object at index 0 of that list does not need to BE the object, it just has to be == the object.
13th Oct 2018, 5:23 PM
HonFu
HonFu - avatar
0
HonFu It should, and I'm happy you made it clear, but some answers seemed to indicate otherwise
13th Oct 2018, 5:27 PM
Emerson Prado
Emerson Prado - avatar