Python is a high-level scripting language. So, when you create a list or a dictionary, the operation seems to be simple, when in fact, lots of lines of code are being executed on the background, instructing the machine to allocate memory in many different ways, to allocate the data structures you need and assign their reference to a variable.
When you execute the following statement, you're creating a list object.
a = []
Which is the same thing as this:
a = list()
list
is a global variable storing the list object constructor. Both lines allocate a list object's instance, and assign the structure's reference to the variable a
.
As lists are used to store multiple elements inside it, you can create an empty list, or an already pre-allocated list:
a = [] # creates an empty list
b = [0] * 10 # creates a list with 10 positions, all of them filled with 0.
c = [0, 1, 2, 3, 4, 5] # creates a list with the elements 0, 1, 2, 3, 4, 5, inserted in this order
d = [0, 1] * 3 # creates this list: [0, 1, 0, 1, 0, 1]
In order to append data to a list (which can be of any type, including other lists), we can use the .append()
method. However, as shown in your example, we can also use ls += [value]
, which is a sugar syntax to ls = ls + [value]
. However, you must take care on using ls += [value]
or ls = ls + [value]
. As you might have noted, I wrote [value]
with brackets, because as an overload operator, the add operations needs a list object on both ends.
Strings are likely a list of characters, so python can implicitely convert "_"
to ["_"[0]]
, meaning it will work. But that's just python easing your life, you shouldn't rely on this mechanism very often.
# both create the same lists:
a = []
for i in range(6): # In terms of efficiency, complexity is O(n)
a.append(i)
b = []
for i in range(6): # In terms of efficiency, complexity is O(n^2), so its slower
b += [i]
# source: https://www.geeksforgeeks.org/difference-between-and-append-in-python/
Now, as lists contain multiple elements inside it, you may eventually need to access these items. List objects use integers to access each element. Each element is stored in a single position inside your list. There're never holes on your list. If you try to remove an item from the middle, the list will be sorted to fill any gaps.
In order to access a list's element you can use: item = ls[index]
, where index
must be an integer.
You must be careful when accessing items from a list. Indexes ranges from [0, len(list)-1]
. If the index is higher than len(list)-1
or lesser than 0
, you will be accessing trash not allocated from memory, which can lead to lot's of errors.
On python, you can also use negative integers to access items from its end. The same way as positive indexes range from [0, len(list)-1]
, negative indexes range from [-len(list), -1]
:
ls = [0, 1, 2, 3, 4, 5]
print(ls[-1]) # This will print 5
print(ls[-6]) # This will print 0
So, this covers the basic of why we use brackets. However, there's way more than this, and go read a tutorial if you need more.