Data Structures and Data Types Primer Flashcards

1
Q

How are lists stored in memory in python? When is memory reallocated?

A

Lists are actually variable-length arrays in Python, not linked lists. Internally they are stored as pointers to elements.

Append: When another element is appended, the list is resized to allocate additional space if needed. In order to avoid costly memory allocation operations, initially more memory is allocated.

Pop: When the last element is popped (removed), if the current list size is less than half of allocated memory, the allocated memory is shrinked.

2
Q

What are the rules for Big O? (4)

A
2. Don’t include constants because they’re not significant enough
3. Different steps get different variables in the O equation
4. Drop non-dominant terms
3
Q

What’s Big O notation?

A

Shows how time scales with respect to some input variables

4
Q

For lists, what are the operations you can do and what’s their big O notation? (3)

A
• Append (add): the list is resized to allocate additional space (i.e. more than is required for just the element(s) being appended) O(n)
• Pop (remove): When the last element is popped (removed), if the current list size is less than half of allocated memory, the allocated memory is shrinked. O(n)
• Accessing: Any element can be directly accessed by its index by calculating its pointer in memory using the offset from pointer to initial element, which makes accessing an O(1) operation
5
Q

Describe Tuples

A
• Tuples are immutable, which means that they can’t be changed.
• Therefore, they are hashable and can be used as keys in dictionaries
6
Q

A

Adding new elements is less expensive than with arrays (aka lists).

7
Q

A
• Each element has a pointer to the next element
• For double linked lists: Stores pointers to each the last and next elements.
8
Q

Describe the operations performed on linked lists and their Big O notation

A
• Adding to end: Need to add to the last element in the list a link to the new element.
• Inserting at position i:
• Traverse to element before where you want to insert.
• Update that element’s pointer to point to the inserted element.
• Update inserted element’s pointer to the element that comes after
• Delete at position i: the element at position i-1 needs to be updated to maintain the link to element i+1
• Accessing element at index i: Traverse all elements until you get the desired element.

access and search are O(n) operations and adding and removing elements (to and from the end) is just O(1) operation

9
Q

A
• Simple linked lists can only be traversed in the forward direction.
• Double linked lists can be traversed in either direction
10
Q

A

queue

11
Q

Library you can use for a linked list in python

A

from collections import deque

12
Q

What are sets?

A
• Unordered
• Has only unique elements

set_example = {1,2,3}

13
Q

Big O for checking if element exists in a set

A

O(1) on average and O(n) in worst case

14
Q

What are sets best for?

A

For operations that require checking whether some value is in some set of values

15
Q

What’s the big O of dictionary operations?

A

getting, adding and deleting an item: O(1)

16
Q

What can the keys and values of dictionaries be?

A
• Keys: Anything hashable?
• Values: Virtually anything?
17
Q

What is hashing?

A

Hashing function is a function that converts some object to a string with next conditions:

1. different objects should have different hashes (though collisions are possible)
2. It should be deterministic and provide the same output for the same inputs.

Hash function is not reversible in general case.

18
Q

What are trees?

A
• A data structure where each element may have multiple links to other elements.
• Each element has a parent - another element that holds a link to that element.
• There should not be any cycles in trees
19
Q

What’s a library used with trees? How’s it used?

A

from nltk import Tree

• Initialize: t = Tree.fromstring(‘(Root (Child1 (Grandchild1 Grandchild2 Grandchild3) Child2))’)
• Generate graphical representation: t.draw()
20
Q

How do you navigate a tree?

A

Recursion is one useful way

Example:

21
Q

What does the number of bits allocated to store values represent?

A

The range of numbers that can be represented, the accuracy and memory requirements.

22
Q

How many bytes to store:

• Boolean
• Char
• String
• Integers
A
• Boolean: 1 byte
• Char: 1, 2 or 4 bytes (based on encoding). The more characters the encoding supports, the more bytes are needed.
• String: Allocated as a fixed size array with each element having an amount of memory allocated that would be equal to the amount of memory needed for the largest encoding. This is done since the string is an array, which requires each element to be using the same amount of memory
• Integers: Int16 uses 2 bytes, while int32 uses 4 bytes and so on. I believe it’s the same for unsigned (e.g. uint32 also uses 4 bytes)
23
Q

Describe signed vs unsigned integers

A
• Unsigned don’t store negative values but can hold larger values than signed ints.
• This is because the first bit isn’t used for the sign
• They both are capable of representing the same number of values
24
Q

Describe a float

A

Might need to add more here

25
Q

How do you determine how many values signed and unsigned ints can represent? What about max vals?

A

Both can represent 2^n values. E.g. int16 = uint16 = 2^16

• Max val signed = 2^(16-1) - 1
• Max val unsigned = (2^16) - 1
26
Q

How do you use numpy to get information about a specific type of float?

A
27
Q

Which structure should be used for Ordered sequence of elements, a lot of edits? Why?

A
28
Q

Which structure should be used for Ordered sequence of elements, create once, read often? Why?

A
29
Q

Which structure should be used for Key-values pairs (one to many)? Why?

A
30
Q

Which structure should be used for Key-value pairs (one to one)? Why?

A
31
Q

Which structure should be used for filtering? Why?

A