It's O(1) for both list and tuple. They are both morally equivalent to an integer indexed array.
Answer from David Heffernan on Stack OverflowIt's O(1) for both list and tuple. They are both morally equivalent to an integer indexed array.
Lists and tuples are indexable in the exact same way arrays are in other languages.
A simplified explanation is that space is allocated for references to objects, those references take up a uniform amount of space, and any index is simply multiplied by the size of the reference to get an offset into the array. This gives constant, O(1), access for lists and tuples.
Hashing Time Complexity in Python
Doubt on analysis on time and space complexity of creating n² tuples - Computer Science Stack Exchange
Time complexity of casting lists to tuples in python and vice versa - Stack Overflow
python - Time complexity of list and tuple lookup - Stack Overflow
When we use strings and tuples as python dictionary keys, is the time complexity of accessing a particular dictionary item (using dictionary[key]) O(n), where n is the length of the string or tuple?
For example, in the code below if n is the length of the input list and k is the maximum length of a string in the input list, is the time complexity O(nk) or O(n)?
def groupStrings(self, strs: List[str]) -> List[List[str]]
groups = []
groupDict = {}
for string in strs:
if string in groupDict:
groups[groupDict[string]].append(string)
else:
groupDict[sortedStr] = len(groups)
groups.append([string])
return groupsIt is an O(N) operation, tuple(list) simply copies the objects from the list to the tuple. SO, you can still modify the internal objects(if they are mutable) but you can't add new items to the tuple.
Copying a list takes O(N) time.
>>> tup = ([1, 2, 3],4,5 ,6)
>>> [id(x) for x in tup]
[167320364, 161878716, 161878704, 161878692]
>>> lis = list(tup)
Internal object still refer to the same objects
>>> [id(x) for x in lis]
[167320364, 161878716, 161878704, 161878692]
But outer containers are now different objects. So, modifying the outer objects won't affect others.
>>> tup is lis
False
>>> lis.append(10)
>>> lis, tup
([[1, 2, 3], 4, 5, 6, 10], ([1, 2, 3], 4, 5, 6)) #10 not added in tup
Modifying a mutable internal object will affect both containers:
>>> tup[0].append(100)
>>> tup[0], lis[0]
([1, 2, 3, 100], [1, 2, 3, 100])
Timing comparison suggest list copying and tuple creation take almost equal time, but as creating a new object with new properties has it's overhead so tuple creation is slightly expensive.
>>> lis = range(100)
>>> %timeit lis[:]
1000000 loops, best of 3: 1.22 us per loop
>>> %timeit tuple(lis)
1000000 loops, best of 3: 1.7 us per loop
>>> lis = range(10**5)
>>> %timeit lis[:]
100 loops, best of 3: 2.66 ms per loop
>>> %timeit tuple(lis)
100 loops, best of 3: 2.77 ms per loop
As far as I understand, there's no bit to switch, as the list (mutable) object is completely different than the tuple (immutable) object. They have different methods etc.
One experiment you might do is this:
>>> a = [1,2,3,4,5]
>>> a = (1,2,3,4,5)
>>> a
(1, 2, 3, 4, 5)
>>> b = list(a)
>>> b
[1, 2, 3, 4, 5]
>>> b[2] = 'a'
>>> b
[1, 2, 'a', 4, 5]
>>> a
(1, 2, 3, 4, 5)
See, if they were referencing the exact place in the memory then a should have changed as well.
That's for my understanding.