list
is an array (Dynamic Array) like implementation in Python. list
is an ordered collection of sequence of items, which can be of any data type or objects.list
is Mutable (values can be changed) and an iterable object (can be iterated using loops, more on this later). It supports Indexing, Slicing, and also Comprehensions, which is a short way of creating a sequence.list
.# Create a empty list using '[]' brackets
some_list = []
# or using the list() function
some_list = list()
# Initialize a list with items inside '[]' brackets
my_list = [1, 1, 3, "a", "cab boy", 4.0]
list
.my_list = [23, 65, 12, 76, 10]
print(my_list) # [23, 65, 12, 76, 10]
## Adding/Appending: Adding values to list
my_var = 1
my_list.append(my_var)
print(my_list) # [23, 65, 12, 76, 10, 1]
## Altering: Change values of list items using indexes
my_list[0] = 100 # 1st element
my_list[4] = 200 # 5th element
print(my_list) # [100, 65, 12, 76, 200, 1]
## Removing: Remove values from list
# eg remove 'my_var' from 'my_list'
my_list.remove(my_var)
print(my_list) # [23, 65, 12, 76, 200]
# remove using 'del' statement is mostly preferred, eg 'del my_list[index]'
del my_list[0]
# or even with slicing, eg 'del my_list[start_index:end_index]'
# or using 'pop()' method of list, eg 'my_list.pop(index)'
# Note: 'del' statement can be used to delete any other object too.
print(my_list) # [65, 12, 76, 200]
## Checking if some value is present in list
if 20 in my_list: # similar to "if some_var in my_list:" where "some_var = 20"
print("not printed")
if 200 in my_list:
print("printed") # printed
list
.## Joining: Join two or more lists
# using '+' operator
my_list1 = [2, 4, 5, 6] + [34, 7, 4, 2]
print(my_list1) # [2, 4, 5, 6, 34, 7, 4, 2]
# using 'extend()' method
my_list1.extend([3, 6, 2])
print(my_list1) # [2, 4, 5, 6, 34, 7, 4, 2, 3, 6, 2]
## Multiplying: Multiply a list using '*' operator
eg_list = ["This", 30]
print(eg_list * 3) # ['This', 30, 'This', 30, 'This', 30]
list
.my_list = [1, 1, 3, "a", "cab boy", 4.0]
my_list1 = [45, 23, 5, 6, 34, 6, 22]
## Indexing: For accessing/altering elements
# as usual index 0 is the first element
var_1 = my_list1[0]
var_2 = my_list1[1]
print(var_1, var_2) # 45, 23
# altering values in list, like we saw above
my_list1[0] = 100
my_list1[-1] = 200
## Iterating: Going over item by item from a list
for var in my_list1:
print(var) # [100, 23, 5, 6, 34, 6, 200]
## Slicing: For creating sub-list, syntax is [start_index:end_index:step]
print(my_list[3:5]) # ['a', 'cab boy']
print(my_list[5:]) # [4.0]
print(my_list[:3]) # [1, 1, 3]
print(my_list[:5:2]) # [1, 3, 'cab boy']
# negative indexing similar to string
print(my_list[:-4]) # [1, 1]
# reverse a list
print(my_list[::-1]) # [4.0, 'cab boy', 'a', 3, 1, 1]
list
comprehension.## List comprehension: Create a new list in a single line
# Note: 'range()' function creates a sequence of integers,
# we'll learn more on range later
my_list1 = [x for x in range(10)]
# this is similar to
my_list1 = []
for x in range(10):
my_list1.append(x)
# comprehensions are syntactic sugar, they save lines of code
# Nesting a list comprehension
my_list2 = [[y for y in range(x)] for x in range(5)]
# Adding if..else conditions
my_list3 = [abc for abc in range(10) if abc > 5]
my_list4 = [True if z > 5 else False for z in range(10)]
# Notice: The syntax difference between if and if..else clauses
# also try printing each of the list
list
.my_list = [1, 2, 3, 4, 5, 6]
new_copy = my_list
del new_copy[0] # deleting first item
print(my_list, new_copy) # [2, 3, 4, 5, 6] [2, 3, 4, 5, 6]
# the deletion is reflected to 'my_list' too, because they refer to same object
# this behaviour is exclusive to mutable objects, this was the catch from
# 'Multiple Target assignment', modifications on mutable objects
# reflect changes to its references too
## Creating a copy
# Using colon in brackets or using "my_list.copy()"
new_copy = my_list[:]
# now they do not refer to the same object
print(id(new_copy), id(my_list)) # 1882455764160 1882447248640
del new_copy[0]
print(my_list, new_copy) # [2, 3, 4, 5, 6] [3, 4, 5, 6]
list
.my_list1 = [10, 50, 40, 50, 60, 80, 15]
# Reverse a list, its inplace so does not return anything
my_list1.reverse()
print(my_list1) # [15, 80, 60, 50, 40, 50, 10]
# Sort a list, also inplace
my_list1.sort()
print(my_list1) # [10, 15, 40, 50, 50, 60, 80]
# Return index of first arrival of a given value
print(my_list1.index(50)) # 3
# Remove a given value from list
my_list1.remove(15)
# Remove a value given a index from list, also returns the value
print(my_list1.pop(5)) # 80
# Empty a list
my_list1.clear()
print(my_list1) # []
list
.my_list1 = [10, 50, 40, 50, 60, 80, 15]
# Return a sorted list of items, ascending order by default
# sorting time complexity is O(nLogn)
print(sorted(my_list1)) # [10, 15, 40, 50, 50, 60, 80]
# for reversing just pass 'reverse=True'
print(sorted(my_list1, reverse=True)) # [80, 60, 50, 50, 40, 15, 10]
# Return the length of list
print(len(my_list1)) # 7
# Return the sum of items
print(sum(my_list1)) # 305
print(sum([10, 20])) # 30
my_list = list((1, 2, 3, 4, 5)) # tuple to list
my_list = list({1, 2, 3, 4, 5}) # set to list
Time Complexity
list
allows to hold data of any data-type/object which is great, but this means the data is usually less tightly coupled, so they end up taking more storage. To hold a large amount of data efficiently one can utilize the array
types.list
they are mutable, iterables, they support indexing, slicing and they even share almost all list
operations. The difference is they allow storing data of limited types only such as characters, numbers and single (same) data type per array. It has to be one of in C language's Data-Types (eg. signed int/unsigned float).array
module. While defining we need to provide the type of data the array
can contain, it can be one of types mentioned in the table shown here.import sys
import array
# Create a normal list
my_list = [54, 32, 65, 32, 65, 32]
# the first parameter is c data type (only the ones mentioned in the table)
# and second is the data from a sequence type such as list/tuple
my_array = array.array("i", my_list)
print(my_array) # array('i', [54, 32, 65, 32, 65, 32])
# 'i' stands for signed integer data type
# create a character data array
char_array = array.array("u", "somestr")
print(char_array) # array('u', 'somestr')
# check their memory usage
print(sys.getsizeof(my_list)) # 152
print(sys.getsizeof(my_array)) # 88
# we can see the difference in bytes, array consumes less space compared to list
array
.import array
my_array = array.array("i", [5, 7, 11, 6, 2, 8, 1])
## Indexing
print(my_array[0]) # 5
## Iterating
for a in my_array:
print(a) # [5,7,11,6,2,8,1]
## Slicing
print(my_array[1:3]) # array('i', [7, 11])
array
.import array
my_array = array.array("i", [5, 3, 5, 5, 2, 7, 8])
my_array.append(30)
print(my_array.index(30)) # 7
my_array.remove(30)
print(my_array.pop(3)) # 5
# extending from array
my_array.fromlist([67, 87])
print(my_array) # array('i', [5, 3, 5, 2, 7, 8, 67, 87])