Complete Interview Study Guide on Python List and Dictionary covering all aspects

7. How do you access the list item by index?

In Python, getting the access to an item of the list can be done via the index by using square brackets [] with the index number written inside. An index starts from 0 for the first item, 1 for the second item and so on. In case you wish to access any item at the desired position just type the index number inside the square brackets.

The following is how an item can be accessed from a list by index:
my_list = [10, 20, 30, 40, 50]
item = my_list[2] # Accesses the element at index 2, which is 30
print(item) # Output will be 30

Explanation:
my_list[2] accesses the third item in the list (since indexing starts from 0), which is 30 in this case.
If you use a negative index (for example my_list[-1]), it accesses the last element from the list, which means that my_list[-1] would return 50, the last item.
Summary:
Index starts from 0, which means, for example, my_list[0] is the first item.
If you attempt to access an index out of range, you will receive an IndexError from Python.


8. What happens if an index is out-of-bounds while attempting to access a list?

An IndexError in python is encountered when a list is accessed with an index that is out of bounds. This means that an index contemplated does not exist in the list.

For the sake of clarity:
my_list = [10, 20, 30]
print(my_list[5]) # Trying to access index 5, which is out of bounds.

Explanation:
The index 0 is given to the first element (10), index 1 to the second element (20) and finally index 2 to the last element (30) in my_list.
Here trying to access index 5 that is more than 2 is not index-out-of-bound hence IndexError will be raised:
The first indication may be the error user typically will see: "IndexError: list index out of range".
You can either verify the validity of the index before access or wrap it up in a try/catch that will catch the error.


9. How many elements does a list contain? (len())

To find the number of elements in a list using Python, you can use its built-in function named len(). The function returns the number of items in a list.
Example:
my_list = [10, 20, 30, 40]
print(len(my_list)) # Output will be 4
For example,
my_list consists of four numeric elements which are 10, 20, 30 and 40.
When you pass my_list to the function len(), it will return 4 as there are some 4 elements in the list.

Points to note:
The built-in len() function is a global function in Python to be used with lists, strings, tuples, dictionaries and all other iterable objects.
It gives the number of values (total count) present in a collection such as a list or any other.


10. How do you slice a list? Give an example.

In Python, slicing a list means getting a portion or a subset of the list by giving a starting index and an ending index. A step can be mentioned alternatively.
Here the slicing is done inside square brackets [] by putting a colon :.

Syntax:
list[start:end:step]
start: The index where slicing starts from (inclusive).
end: The index where slicing ends (exclusive).
step: Optional, it indicates the step or gap between each element.

Example:
my_list = [10, 20, 30, 40, 50, 60, 70]
sliced_list = my_list[2:5]
print(sliced_list) # Output: [30, 40, 50]

Explanation:
In this example, my_list[2:5] slices up starting from index 2 (which is 30) and slices up to but not including index 5 (which is 50).
Hence, the sliced list will be [30, 40, 50].

Next Examples:
Slicing with Step:
my_list = [10, 20, 30, 40, 50, 60, 70]
sliced_list = my_list[1:6:2]
print(sliced_list) # Output: [20, 40, 60]
So slicing is done from index 1 to index 6 having the value of 2 as a step to measure every second element.

Omitting Start or End:
Omitting start would mean here for slicing from the beginning:
sliced_list = my_list[:4] # Output: [10, 20, 30, 40]

Omit end to slice till the end:
sliced_list = my_list[3:] # Output: [40, 50, 60, 70]
Negative Indexing: Negative indices can also be used to slice from the rear of the list.
sliced_list = my_list[-4:-1] # Output: [40, 50, 60]

Key Points:
Slicing does not modify the original list, instead it returns a new list. In any case, if an index goes out of bounds, Python will take care of it automatically (for example, negative indices will count from the end of the list).


11. How do you reverse the order of all items in a list? (.reverse() or slicing)

Reversal of lists is done in Python using the .reverse() method or slicing. Both methods give reversed lists, but they differ in how they work.
1. The .reverse() method: This modifies the original list and changes the order of elements to reversed order.
fruits = ['apple', 'banana', 'cherry']
fruits.reverse()
print(fruits) # Output: ['cherry', 'banana', 'apple']

2. Slicing method ([::-1]): This makes a new list, which is reversed in respect to the original.
fruits = ['apple', 'banana', 'cherry']
reversed_fruits = fruits[::-1]
print(reversed_fruits) # Output: ['cherry', 'banana', 'apple']

One must remember the point of importance:
- The .reverse() function deprecated changes to the original list.
- Slicing ([::-1]) creates a new reversed list leaving the original one intact.
Either way, this is very easy depending on the case for displaying the items in reverse order.


12. How do you sort a list in Python? (.sort())

In the Python programming language, the ascending sort for a list's contents can be efficiently carried out using the built in .sort() method to arrange the items and modify the initial instance of the list itself.

The general syntax:
list.sort().

Example:
numbers = [5, 2, 9, 1, 7]
numbers.sort()
print(numbers) # Output: [1, 2, 5, 7, 9]

Explanation:
.sort() organizes list in place which means it does not return a new list.
Sorting is done in ascending order by default.

In order to sort in descending order use reverse=True option:
numbers.sort(reverse=True)
print(numbers) # Output: [9, 7, 5, 2, 1]
It works for lists in either numbers or strings giving you an easy way to keep your data in order.


13. How do you create a new sorted list from an existing list? (sorted())

In Python, built-in function sorted() allows the sorting of a new list to be returned without modification of the old list.

This is how it works:
numbers = [5, 2, 9, 1, 7]
new_list = sorted(numbers)
print(new_list) # [1, 2, 5, 7, 9]
print(numbers) # [5, 2, 9, 1, 7] (original list is untouched)

Point to Note:
sorted() gives a brand new sorted list.
The original list keeps its order.
In addition, if you wish to sort in reverse order, just add the reverse=True argument, like this:
sorted(numbers, reverse=True)
This is sometimes useful when you wish to keep the original data untouched and work with a sorted version.


14. What is list comprehension? Give an example of list comprehension that creates a list of squares.

In one line, list comprehension gives a concise way to tell how a new list is created — an operation performed on each one of another list or a range.
List comprehension is often used in cases where you want to build up a list on the fly using some loop like syntax.

For example, let’s create a list of squares from 1 to 5:
squares = [x**2 for x in range(1, 6)]
print(squares) # Output : [1, 4, 9, 16, 25]

Here, x**2 is the operation which is performed for each x in the range from 1 to 5. It looks like a for loop but much cleaner and easier to read.


15. How do you check for membership of an item in a list? (using in operator)

The in operator is for simple membership testing to test whether that value is in that particular list. If the value happens to be found, it returns True, otherwise returns False. Membership testing is most broadly used with the in operator as part of a condition that is going to determine the presence or absence of a value.

Example:
colors = ['red', 'blue', 'green']
print('blue' in colors) # Output: True
print('yellow' in colors) # Output: False

This brief example demonstrates the use of this operator to verify the existence of a particular value in a Python list. In this case, it was possible to efficiently scan the colors list. The first check 'blue' in colors returns True because 'blue' is present. The second check 'yellow' in colors returns False as 'yellow' is not in the list. This shows a powerful but simple method of python membership testing, which determines whether a specific element is contained in the collection.


16. What is a dictionary in Python? What is its difference from a list?

Dictionaries in Python are the representation of data in pairs of keys and values, where each key can be seen as some kind of identification referring to a particular data called value. This makes dictionaries the most useful in situations when data has to be stored with some identification.

An example could include details of a person:
person = {
"name": "Alice",
"age": 25,
"city": "Pune"
}
Here, name, age and city are keys pointing to their respective values. If you want to access Alice's city directly, get it with person["city"]. It is that simple, clear and keeps your code neat.

What is a List in Python?
A list is an ordered collection of items. It is used when the order of elements is very important. List items are enclosed in square brackets and can be accessed based on their position starting from the index 0.

The following is an example:
person_list = ["Alice", 25, "Pune"]
With respect to the name, it is just simply person_list[0]. Some of these work for very simple items.It works well for simple collections, but it's not always clear what each value means unless you already know the order.

Key Differences
The main difference affecting lists and dictionaries pertains to their access schemes and to one's state of mind in thinking about a data issue. In a dictionary, objects are retrieved via name or key, the technique most suited for labeled structured information. While in a list, it is retrieval depending upon position, which one may take recourse to only when all objects are similar, more or less and their position means something.

When to Use What
Use the dictionary whenever your data has proper labels, such as for records or attributes. Use a list whenever dealing with the collection of items that needn't be bothered about labeling, such as numbers, names or steps in a process.


17. How do you create an empty dictionary in Python?

In Python, a dictionary is a data structure that organizes data such that each object has a label (called a key) and a corresponding value. for instance, a person's name related to his/her age or city.
To develop such a structure, the first step is to create an empty dictionary. And It can be created using the following given ways.

Option 1: Through Using {} (Curly Braces)
An empty dictionary can simply be created by one of the most commonly used ways as simply: my_dict = {}
This line simply creates a dictionary with nothing inside it yet. It is like opening a new notebook with blank pages.

Option 2: Through Using the dict() Function
Alternatively, we could do this by using:
my_dict = dict()
This also creates an empty dictionary. Some people prefer this style as it somehow makes their code clearer and more readable.
Once you've created your dictionary, you can start adding stuff.
For instance:
my_dict["name"] = "Alice"
my_dict["age"] = 25
And now your dictionary looks like this:
{'name': 'Alice', 'age': 25}
So, there you go! Feel free to fill it with useful information even when it started empty.

Conclussion
Creating an empty dictionary is just the beginning. Its main intent is to specify information against the labels. Whether you do it with {} or dict() there is no difference in functionality. Just follow your sense of readability in the code.


18. How do you add a new key-value pair to a dictionary?

Adding a new key-value pair to a dictionary in Python is undoubtedly a straightforward task, and there are actually multiple ways to go about it. Find out the few simple methods of adding new data to your dictionary!

1. Simple Assignment
The simplest way to add values is to use just simple assignment. Tell the key (the name) and value (the information to be stored).
# Adding a new key-value pair
my_dict['city'] = 'New York'

Example:
You have a dictionary on a person.
my_dict = {'name': 'Alice', 'age': 25}
And you want to now add to that, like the city Alice lives in. Then you just do this:

# Adding a new pair
my_dict['city'] = 'New York'

# Output: {'name':'Alice', 'age': 25, 'city':'New York'}
This is straightforward and allows a single item to be easily added.

2. Using the update() Method
In case of adding more than one item at a time, update() is a very good alternative. This method allows you to add many key-value pairs at once.

# Adding multiple key-value pairs
my_dict.update({'country': 'USA', 'job': 'Engineer'})
Example:
print(my_dict)
# Output: {'name': 'Alice', 'age': 25, 'city': 'New York', 'country': 'USA', 'job': 'Engineer'}
This is useful when you have many things to add at once!

3. Using setdefault()
The setdefault() method is special in that it only adds a key-value pair if that key does not exist already. If the key is already in the dictionary, it will not change the value.
# Adds 'city' only if it doesn't already exist
my_dict.setdefault('city', 'Los Angeles')
Example:
If 'city' happened to be there, for example, it wouldn't do anything while if 'city' did not exist, it would add 'Los Angeles'.

4. Using the dict() Constructor
You can also create a new dictionary with key-value pairs by dict(). This is helpful when you want to start a brand-new dictionary.
# Using dict() to create a new dictionary
my_dict = dict(name='Alice', age=25, city='New York')


19. How do you access a value from a dictionary when you have the corresponding key?

The easy working with accessing the value from the dictionary in Python when we have a key is explained herewith with two usual ways of doing the same:

1. Using Square Brackets ([])
The easiest way that anyone can access value is to use the square brackets with a key inside it. If the key is there, Python will return the value.
# A sample dictionary
my_dict = {'name': 'Alice', 'age': 25, 'city': 'New York'}
# Accessing the value using the key 'name'
print(my_dict['name']) # Output: Alice
This is a predominant way of value access from the dictionary!

2. Using the get() Method
Another way to retrieve a value is through get(). This acts just like the square brackets, but if the key doesn't exist, it won't throw an error, it simply returns None instead (or another default value, if you supply one).
# Value accessed using get()
print(my_dict.get('age')) # Output: 25
print(my_dict.get('country')) # Output: None (Key not in dictionary)
You can also provide a default value to return if the key is not found:
# If 'country' doesn't exist, it will return 'Unknown'
print(my_dict.get('country', 'Unknown')) # Output: Unknown

Quick Recap:
Square brackets ([]) is the fastest way to get a value when you are sure that the key exists.
get() is safer, as it does not throw an error if the key is not present and you can provide an alternative value for it to return.


20. What happens if you try to access a value in a dictionary using a key that doesn't exist?

When accessing a key that is not present in the dictionary, Python may behave in two distinct ways based on how one tries to access the value.

1. Using Square Brackets ([]) - Error is shown
If the key is not in the dictionary and the square brackets are used, then Python will generate a KeyError telling that there was no such key. This causes the halt to the program.
my_dict = {'name': 'Alice', 'age': 25}
print(my_dict['city']) # This will throw a KeyError
Output:
KeyError: 'city'
So if you don't know whether the key is there, it's better not to use square brackets directly.

2. get() uses - No Error
In the case of using the get() method, there will not be any error generated and if there is no key, it will return None or some value selected by you.
# Key doesn't exist, hence returns None
print(my_dict.get('city')) # Output: None
# You can also give a default value
print(my_dict.get('city', 'Not found')) # Output: Not found
This way is safer especially when not sure whether the key is in the dictionary or not.

Summary:
Using [] with a missing key will stop your code with an error.
Using get() is safer. It won't stop your code and can return a default value if the key isn't found.
Get() is the better option for scenarios where you are not sure if the key exists.


21. How do you tell if a key exists in a dictionary? (using in operator)

The in operator can verify a key's existence within a dictionary. It checks whether the key is in the dictionary and returns either True or False, depending on whether it is present.
Example:
my_dict = {'name': 'Alice', 'age': 25}
if 'age' in my_dict:
  print("Key exists")

Code Explanation:
We are checking here if 'age' is one of the keys in the dictionary my_dict. Since it exists, the program prints "Key exists".


22.How do you delete key-value pairs in a dictionary? (.pop(), del)

There are two methods available to delete key-value pairs from a dictionary in Python .pop() and del. Both work in a different manner, but both are useful.

1. Using .pop() Method
The .pop() method takes the key value pair from the dictionary and also returns the associated value.
my_dict = {'name':'Alice', 'age': 25, 'city':'Pune'}
# Remove 'age' and return that value
age = my_dict.pop('age')
print(age) # Output: 25
print(my_dict) # Output: {'name':'Alice', 'city':'Pune'}
Note: If the key doesn't exist, .pop() will raise KeyError unless you give a default value to return.

2. Using del Keyword
The del keyword simply removes the key value pair without returning the value.
my_dict = {'name':'Alice', 'age': 25, 'city':'Pune'}
# Removes the 'city' key-value pair
del my_dict['city']
print(my_dict) # Output: {'name':'Alice', 'age': 25}
Note: If the key doesn't exist, there will be a KeyError raised by del.

Summary:
pop() removes the key value pair and returns the value.
del removes the key value pair with no return at all.
While both are useful, choose based on your need to obtain the value removed or not.


23.How do you obtain a list of all keys in a dictionary? (.keys())

To fetch all the existing keys from a dictionary the easiest method is to use the query .keys().
It gives you a unique view of the keys of a dictionary.

Example:
my_dict = {'name':'Alice','age':25, 'city':'Pune'}
# From the dictionary to get all keys
keys=my_dict.keys()
print(keys)
# Output: dict_keys(['name', 'age', 'city'])
Note: This output resembles a specialized view rather than an exact list, but you can easily transform it into a list if necessary.

# Convert keys to list
keys_list=list(keys)
print(keys_list)
# Output: ['name', 'age', 'city']
Key Points:
1. .keys() gives a view of the keys existed in the dictionary.
2. Convert this view into a list using list() if you want.


24.How do you obtain a list of all values in a dictionary? (.values())

The .values() method helps extract values contained in the dictionary.
.values() gives a view of all the values available in the dictionary and is special.

Example:
my_dict = {'name': 'Alice', 'age': 25, 'city': 'Pune'}
# To get all the values from the dictionary:
values = my_dict.values()
print(values) # 'Alice' '25' 'Pune' are all values, the output shows:
dict_values(['Alice', 25, 'Pune'])
Note: It is a special view and does not give a list. But it can be convert it into a list if necessary.
# From the 'values' view to a list
valuesList = list(values)
print(valuesList) # ['Alice', 25, 'Pune']

Key Points.
.values() gives you a view of all the values in the dictionary.
If you want to make sure it is a list you can apply the list() conversion.


25.How do you iterate over a dictionary and retrieve both keys and values? (.items())

You can access the both key and value in a loop with the .items() method of a dictionary. It allows getting the key and value atonce.

Example:
my_dict = {'name': 'Alice', 'age': 25, 'city': 'Pune'}
# To iterate the dictionary and access both key and value#

for key, value in my_dict.items():
  print(f"Key: {key}, Value: {value}")
Output:
Key: name, Value: Alice
Key: age, Value: 25
Key: city, Value: Pune

Key points:
.items() gives you both key and value while looping a dictionary.
You could easily get both just in a single step using a for loop.


26.What is dictionary comprehension? Give an example of using it to construct a new dictionary with altered values.

The dictionary comprehension is an elegant way and in one line a new dictionary can be created from an old one by changing keys or changing its values.
Example: Let's say you have a dictionary and want all values to be doubled:

old_dict = {'a': 1, 'b': 2, 'c': 3}
# Make a new dictionary with values doubled
new_dict = {key: value * 2 for key, value in old_dict.items()}
print(new_dict) # Outputs: {'a': 2, 'b': 4, 'c': 6}

Key Points:
It uses a for loop inside {} to create the new dictionary.
An advantage is that we can quickly change values or keys.
It makes the code clean and readable.


27.Can you apply comprehensions for filtering items from a list or a dictionary? Provide examples.

The comprehensions can be performed such that from a list, for example, a few selected items get picked up to filter with simple conditions.

List filtering: Example 1
From a list of numbers, we shall filter and keep only the even ones.
numbers = [1, 2, 3, 4, 5, 6]
# Keep only even numbers
even_numbers = [num for num in numbers if num % 2 == 0]
print(even_numbers) # Output: [2, 4, 6]

Dictionary filtering: Example 2
Let us assume we want to filter the students whose scores were above 50 marks.
marks = {'Alice': 45, 'Bob': 75, 'Carol': 60, 'Dave': 40}
# Keep only students with marks greater than 50
passed = {name: score for name, score in marks.items() if score > 50}
print(passed) # Output: {'Bob': 75, 'Carol': 60}

Key Point:
To filter what you want, just include an if condition.
This works for both lists and dictionaries.
This simple principle makes your code short, simple, and readable.


28.Is it possible to have multiple instances of the same key in a Python dictionary? Give reasons if yes or no.

A dictionary can't have the same key twice in Python.
Why?
All the keys should be unique in a dictionary. If we use the same key again, Python will overwrite the value present with the new value and will not keep both.
Example:
my_dict = {'a': 1, 'b': 2, 'a': 3}
print(my_dict) # =Output: {'a': 3, 'b': 2}
The second one 'a' changes the other one.
So 'a': 1 is no more and 'a': 3 stays.

Quick Note:
Keys in the dictionaries must be unique.
In the case of repetition, only the last one takes effect.
Keeps it clean and understandable while searching.


29. Is it possible to have multiple instances of the same value in a Python dictionary? Give reasons if yes or no.

The same value in a Python dictionary can be repeated many times. Different keys are always important!

Why?
Python only checks for unique keys, it does not care about value repetition. So two different keys can have exactly the same value.
Example:
my_dict = {'apple': 10, 'banana': 20, 'cherry': 10}
print(my_dict)
# Output: {'apple': 10, 'banana': 20, 'cherry': 10}
In the above example, both "apple" and "cherry" represent value 10. That's absolutely fine.

A quick tip:
Keys must be different.
Values may be the same.
This is useful when multiple items have the same number, label or result.


30.How do you create a copy of a dictionary? (.copy())

The .copy() method is used to make a duplicate copy of the dictionary. This one gives rise to a new dictionary containing the same key-value pairs.

Example:
original = {'name': 'John', 'age': 30}
# Make a copy
copy_dict = original.copy()
print(copy_dict)
# Output: {'name': 'John', 'age': 30}

Why to use .copy()?
If you say new_dict = original, both of them will point to the same dictionary: changing the content in one of them will change the content in another. Using .copy() creates a new copy, so the original is safe from any alteration done in the copy.

Quick Points:
.copy() creates a separate copy.
Original and copy can be referred and operated upon separately.
Useful when you wish to keep the original safe while you work on the copy.