5. Data Structures
How to add an item to the end of the list with a built-in method and equivalent slice assign method?
list.append(x)
. Equivalent to a[len(a):] = [x]
.
Extend the list by appending all the items from the iterable.
list.extend(iterable)
. Equivalent to a[len(a):] = iterable
.
Insert an item into list at a given position.
list.insert(i, x)
. The first argument is the index of the element before which
to insert. so a.insert(0, x)
inserts at the front of the list, and
a.insert(len(a), x)
is equivalent to a.append(x)
.
List method to remove the first item from the list whose value is equal to
x. What if there is no such item?
list.remove(x)
. It raises a ValueError
if there is no such item.
Remove the item at the given position in the list, and return it.
What if the list is empty or the index is outside the list range.
list.pop([i])
If no index is specified, a.pop()
removes and returns the last item in the
list. It raises an IndexError
if the list is empty or the index is
outside the list range.
Remove all items from the list.
list.clear()
. Equivalent to del a[:]
.
Return zero-based index in the list of the first item whose value is equal to
x. Can we limit somehow the search to a particular subsequence of the list?
list.index(x[, start[, end]])
Raises a ValueError
if there is no such item.
The optional arguments start and end are interpreted as in the slice
notation and are used to limit the search to a particular subsequence of
the list. The returned index is computed relative to the beginning of
the full sequence rather than the start argument.
Return the number of times x appears in the list.
list.count(x)
Sort the items of the list in place
list.sort(*, key=None, reverse=False)
Reverse the elements of the list in place.
list.reverse()
Return a shallow copy of the list.
list.copy()
. Equivalent to a[:]
.
You might have noticed that list methods like insert
, remove
or sort
that
only modify the list have no return value printed — they return the ==default
None
==. This is a design principle for all mutable data structures in Python.
Other languages may return the mutated object, which allows method chaining,
such as d->insert("a")->remove("b")->sort();
.
When data in list can’t be sorted?
Not all data can be sorted or compared. For instance, [None, 'hello', 10]
doesn’t sort because integers can’t be compared to strings and None
can’t be
compared to other types. Also, there are some types that don’t have a defined
ordering relation. For example, 3+4j < 5+7j
isn’t a valid comparison.
Order of adding/retrieving items from the stack?
How stack can be implemented using list?
Here used LIFO (last-in, first-out) data manipulation. For example, you have
list of cards, if you add a card to the top of the stack, it will be the first
card you can retrieve.
Using python we can use list.append
to add an item to the top of the stack,
and list.pop
without an explicit index to retrieve an item from the top of the
stack.
Order of adding/retrieving items from the queue?
How to better implement a queue and which data structure to use?
Here used FIFO (“first-in, first-out”) data manipulation.
Who come first, will be served first. For example, you have a list of people
waiting in line, the first person added to the list will be the first person
retrieved to be served.
It is also possible to use a list as a queue, where the first element added is
the first element retrieved ; however, lists are not efficient for this purpose.
While appends and pops from the end of list are fast, doing inserts or pops from
the beginning of a list is slow (because all of the other elements have to be
shifted by one, ).
To implement a queue, use collections.deque
which was designed to have
fast appends and pops from both ends. For example:
List comprehensions provide a concise way to create lists. We create them with some operation applied to each member of another sequence or iterable, or to create a subsequence of those elements that satisfy a certain condition.
What side effect is here, how to avoid it?
That this creates (or overwrites) a variable named x
that still
exists after the loop completes. We can calculate the list of squares
without any side effects using:
How I can use multiple list comprehensions in one expression?
A list comprehension consists of brackets containing an expression
followed by a for
clause, then zero or more for
or if
clauses.
The result will be a new list resulting from evaluating the expression
in the context of the !for
and !if
clauses which follow it. For
example, this listcomp combines the elements of two lists if they are
not equal:
Examples how list comprehensions can be used?
Can I use complex expressions and nested functions in list comprehensions?
Yes.
The initial expression in a list comprehension can be any arbitrary expression,
including another list comprehension.
For example:
To remove items from list by index you can use ==del
== statement, unlike
.pop()
method it doesn’t return value. It can also be used to remove slices
from a list or clear the entire list (like assignment of an empty list to the
slice)
How to delete entire variables with del
?
del a
Referencing the name a
hereafter is an error (at least until another value is
assigned to it). We’ll find other uses for del
later.
What type of this data structures?
A tuple, which consists of a number of values separated by commas.
Tuples may be input with or without surrounding parentheses, although often
parentheses are necessary anyway (if the tuple is part of a larger expression).
But they can contain mutable objects, which can be changed
To construct empty tuple need to use ==pair of parentheses, empty = ()
==.
How to construct a tuple with one item?
A tuple with one item is constructed by following a value with a comma (it is
not sufficient to enclose a single value in parentheses). Ugly, but effective.
How to use tuple packing?
You need to construct a tuple with multiple values separated by commas.
How to use tuple unpacking (sequence unpacking)?
You need to assign a tuple to a variable(s), the number of variables should be
equal to the number of values in the tuple.
Note that multiple assignment is really just a combination of tuple packing and
sequence unpacking.
A set is an unordered collection with no duplicate elements.
How to create empty and non-empty sets?
You need to use set()
to create an empty set ({}
used to create empty
dictionary), and curly braces {1}, {1, 2}
to create a non-empty set.
Set operations on unique letters from two words, lets we have two words,
abracadabra
and alacazam
, what results you get for -
, |
, &
, ^
operations?
Results:
{'r', 'c', 'a', 'b', 'd'}
{'c', 'z', 'm', 'a', 'l'}
{'r', 'b', 'd'}
{'r', 'c', 'z', 'm', 'a', 'b', 'd', 'l'}
{'c', 'a'}
{'r', 'b', 'l', 'd', 'z', 'm'}
Can we use comprehensions with sets?
Yes, set comprehensions are also supported:
“Associative memories” or “associative arrays” in Python are implemented as dictionaries.
Which types of keys (general type) can be used in dictionaries?
Dictionaries are indexed by keys which can be any immutable type and unique
(within one dictionary). Tuples can be used as keys if they contain only
strings, numbers, or tuples; if a tuple contains any mutable object either
directly or indirectly, it cannot be used as a key. You can’t use lists as keys,
since lists can be modified in place using index assignments, slice assignments,
or methods like list.append
and list.extend
.
How to create empty and non-empty dictionaries?
A pair of braces creates an empty dictionary: {}
.
Placing a comma-separated list of key:value pairs within the braces adds initial
key:value pairs to the dictionary; this is also the way dictionaries are written
on output.
What is main operations on a dictionary?
The main operations on a dictionary are storing a value with some key
and extracting the value given the key.
How to delete a key:value pair from a dictionary, overwrite key value?
How to get a list of all keys in a dictionary in insertion order and sorted
order?
Performing list(d)
on a dictionary returns a list of all the keys used
in the dictionary, in insertion order (if you want it sorted, just use
sorted(d)
instead).
To check whether a single key is in the dictionary, use the ==in
== keyword.
How to build dictionary from sequence like this [('sape', 4139), ('guido', 4127), ('jack', 4098)]
(key-value pairs)?
The dict
constructor builds dictionaries directly from sequences of key-value
pairs:
How to generate dict using dictionary comprehensions and this sequence (2, 4, 6)
, key is number
, value is number**2
?
Dict comprehensions can be used to create dictionaries from
arbitrary key and value expressions:
Is it possible to use keyword arguments to create a dictionary?
Yes, when the keys are simple strings, it is sometimes easier to specify
pairs using keyword arguments:
When looping through dictionaries, the key and corresponding value can
be retrieved at the same time using the ??? method:
dict.items
When looping through a sequence, the position index and corresponding
value can be retrieved at the same time using the ??? function:
enumerate
To loop over two or more sequences at the same time, the entries can be
paired with the ??? function:
zip
To loop over a sequence in reverse, first specify the sequence in a
forward direction and then call the ??? function:
reversed
To loop over a sequence in sorted order, use the ??? function:
sorted
. Which returns a new sorted list while leaving the source unaltered.
How to loop over a sequence in sorted order while removing duplicates?
Using set
on a sequence eliminates duplicate elements. The use of
sorted
in combination with set
over a sequence is an idiomatic way
to loop over unique elements of the sequence in sorted order:
How to change a list while you are looping over it?
It is sometimes tempting to change a list while you are looping over it;
however, it is often simpler and safer to create a new list instead:
Which operators can contain the conditions used in while
and if
statements
They can contain any operators, not just comparisons. For example:
in
andnot in
, membership (in container?) testsis
andis not
, compare objects is the same object- multiple comparisons (chains) like
a < b == c
- a is less than b and moreover b equals c - combinations with boolean operators
and
,or
,not
All comparison operators have the same priority, which is lower than that of all numerical operators.
Who have more priority comparison operators or Boolean operators?
Boolean operators have lower priority than comparison operators.
A and not B or C
is equivalent to (place parentheses) ==(A and (not B)) or C
==.
The Boolean operators and
and or
are so-called short-circuit operators:
their arguments are evaluated from (direction) left to right, and evaluation
stops as soon as the outcome is determined.
When used as a general value and not as a Boolean, the return value of a short-circuit operator is the last evaluated argument.
Note that in Python, unlike C, assignment inside expressions must be done
explicitly with the ==walrus operator - :=
==. This avoids a common class of
problems encountered in C programs: typing =
in an expression when ==
was
intended.
Sequence objects typically may be compared to other objects with the same sequence type.
The sequence comparison uses lexicographical ordering: first the first two items are compared, and if they differ this determines the outcome of the comparison; if they are equal, the next items (same amount) are compared, and so on, until either sequence is exhausted.
If two items to be compared are themselves sequences of the same type, the lexicographical comparison is carried out recursively. If all items of two sequences compare equal, the sequences are considered equal. If one sequence is an initial sub-sequence of the other, the shorter sequence is the smaller (lesser) one. Lexicographical ordering for strings uses the Unicode code point number to order individual characters. Some examples of comparisons between sequences of the same type:
Note that comparing objects of different types with <
or >
is legal
provided that the objects have appropriate comparison methods. For
example, mixed numeric types are compared according to their numeric
value, so 0 equals 0.0, etc. Otherwise, rather than providing an
arbitrary ordering, the interpreter will raise a ==TypeError
== exception.