Day 3 Python 2024

Overview of Dictionaries & Sets in Python interview level & problems

Table of contents

1. What is a Dictionary in Python?

A dictionary is a collection of key-value pairs. It is an unordered, mutable, and indexed collection that is used to store data values like a map.

Key Characteristics:

  1. Unordered: The items in a dictionary are not ordered.

  2. Mutable: The dictionary can be changed after its creation.

  3. Indexed: Dictionary items are accessed via keys.

  4. Keys must be unique: No duplicate keys are allowed.

  5. Keys must be immutable types: Such as strings, numbers, or tuples with immutable elements.

Creating a Dictionary

You can create a dictionary using curly braces {} with key-value pairs separated by a colon :.

my_dict = {
    "name": "Srinidhi",
    "age": 22,
    "city": "Hyderabad"
}

Accessing Items

You can access the items of a dictionary by referring to its key name, inside square brackets.

print(my_dict["name"])  # Output: Srinidhi

You can also use the get() method.

print(my_dict.get("age"))  # Output: 22

Adding and Changing Items

To add or change an item, simply refer to its key.

my_dict["age"] = 23
my_dict["profession"] = "Engineer"

Removing Items

You can remove an item using the pop() method or the del keyword.

my_dict.pop("city")
del my_dict["profession"]

Dictionary Methods

  • clear(): Removes all elements from the dictionary.

  • copy(): Returns a shallow copy of the dictionary.

  • fromkeys(seq[, v]): Returns a new dictionary with keys from seq and value v.

  • items(): Returns a view object that displays a list of a dictionary's key-value tuple pairs.

  • keys(): Returns a view object that displays a list of all the keys in the dictionary.

  • popitem(): Removes and returns an arbitrary key-value pair from the dictionary.

  • setdefault(key[, default]): Returns the value of a key if it is in the dictionary. If not, it inserts the key with a specified value.

  • update([other]): Updates the dictionary with elements from another dictionary object or from an iterable of key-value pairs.

  • values(): Returns a view object that displays a list of all the values in the dictionary.

Iterating Through a Dictionary

You can iterate through the keys, values, or key-value pairs.

for key in my_dict.keys():
    print(key)

for value in my_dict.values():
    print(value)

for key, value in my_dict.items():
    print(key, value)

Dictionary Comprehension

Just like list comprehensions, you can create dictionaries using dictionary comprehensions.

squares = {x: x*x for x in range(6)}
print(squares)  # Output: {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

Nested Dictionaries

A dictionary can contain dictionaries as values, creating nested dictionaries.

nested_dict = {
    "first": {"name": "Srinidhi", "age": 22},
    "second": {"name": "Ananya", "age": 23}
}

Practical Examples

  • Count the frequency of characters in a string:

      string = "interview"
      frequency = {}
      for char in string:
          if char in frequency:
              frequency[char] += 1
          else:
              frequency[char] = 1
      print(frequency)  # Output: {'i': 2, 'n': 1, 't': 1, 'e': 2, 'r': 1, 'v': 1, 'w': 1}
    
  • Group a list of items by a key:

      data = [
          {"name": "Srinidhi", "group": "A"},
          {"name": "Ananya", "group": "B"},
          {"name": "Ayesha", "group": "A"}
      ]
      grouped_data = {}
      for item in data:
          group = item["group"]
          if group not in grouped_data:
              grouped_data[group] = []
          grouped_data[group].append(item)
      print(grouped_data)
      # Output: {'A': [{'name': 'Srinidhi', 'group': 'A'}, {'name': 'Ayesha', 'group': 'A'}], 'B': [{'name': 'Ananya', 'group': 'B'}]}
    

Understanding dictionaries thoroughly and being able to use them efficiently is crucial for Python programming and will be valuable in technical interviews.

2. Sets

Sets in Python

Sets are a collection data type in Python, similar to lists or dictionaries. They are unordered, meaning that the items do not have a defined order. This also means that the items cannot be accessed using an index. Sets are mutable, but the elements contained within the set must be immutable.

Key Characteristics of Sets:

  1. Unordered: The elements have no specific order.

  2. No Duplicates: Sets do not allow duplicate elements.

  3. Mutable: You can add or remove elements from a set.

  4. Elements must be immutable: But the set itself is mutable.

Creating a Set

You can create a set by using the set() function or by placing a comma-separated sequence of elements within curly braces {}.

# Using set() function
my_set = set([1, 2, 3, 4])

# Using curly braces
another_set = {1, 2, 3, 4}

Adding Elements

You can add elements using the add() method.

my_set.add(5)

Removing Elements

You can remove elements using the remove() or discard() methods. The difference is that remove() will raise an error if the element does not exist, while discard() will not.

my_set.remove(5)
my_set.discard(4)

You can also use the pop() method to remove an arbitrary element and return it.

element = my_set.pop()

To remove all elements, use the clear() method.

my_set.clear()

Set Operations

Sets support mathematical operations like union, intersection, difference, and symmetric difference.

Union

The union of two sets is a set containing all elements from both sets.

set1 = {1, 2, 3}
set2 = {3, 4, 5}
union_set = set1.union(set2)  # or set1 | set2
# union_set = {1, 2, 3, 4, 5}

Intersection

The intersection of two sets is a set containing only the elements that are in both sets.

intersection_set = set1.intersection(set2)  # or set1 & set2
# intersection_set = {3}

Difference

The difference of two sets is a set containing the elements of the first set that are not in the second set.

difference_set = set1.difference(set2)  # or set1 - set2
# difference_set = {1, 2}

Symmetric Difference

The symmetric difference of two sets is a set containing elements that are in either of the sets, but not in both.

symmetric_difference_set = set1.symmetric_difference(set2)  # or set1 ^ set2
# symmetric_difference_set = {1, 2, 4, 5}

Subset and Superset

You can check if a set is a subset or superset of another set using the issubset() and issuperset() methods.

setA = {1, 2, 3}
setB = {1, 2, 3, 4, 5}
is_subset = setA.issubset(setB)  # True
is_superset = setB.issuperset(setA)  # True

Frozen Sets

A frozenset is an immutable version of a set. You create a frozenset using the frozenset() function.

frozen_set = frozenset([1, 2, 3, 4])

Practical Examples

  • Removing duplicates from a list:

      my_list = [1, 2, 2, 3, 4, 4, 5]
      unique_elements = list(set(my_list))
      print(unique_elements)  # Output: [1, 2, 3, 4, 5]
    
  • Finding common elements in two lists:

      list1 = [1, 2, 3, 4]
      list2 = [3, 4, 5, 6]
      common_elements = list(set(list1).intersection(list2))
      print(common_elements)  # Output: [3, 4]
    

Important Set Methods

  • add(element): Adds an element to the set.

  • clear(): Removes all elements from the set.

  • copy(): Returns a copy of the set.

  • difference(set): Returns the difference of two or more sets as a new set.

  • difference_update(set): Removes all elements of another set from this set.

  • discard(element): Removes an element from the set if it is a member (does not raise an error if the element is not a member).

  • intersection(set): Returns the intersection of two sets as a new set.

  • intersection_update(set): Updates the set with the intersection of itself and another.

  • isdisjoint(set): Returns True if two sets have a null intersection.

  • issubset(set): Returns True if another set contains this set.

  • issuperset(set): Returns True if this set contains another set.

  • pop(): Removes and returns an arbitrary element from the set.

  • remove(element): Removes an element from the set. Raises a KeyError if the element is not found.

  • symmetric_difference(set): Returns the symmetric difference of two sets as a new set.

  • symmetric_difference_update(set): Updates the set with the symmetric difference of itself and another.

  • union(set): Returns the union of sets as a new set.

  • update(set): Updates the set with the union of itself and others.

Sets are a fundamental data structure in Python that provide a powerful and efficient way to handle collections of unique items and perform common mathematical set operations. Understanding sets and their operations is crucial for interview preparation and practical Python programming.

  • Day 3

    Problem 1: Word Frequency Count

    Problem: Given a string, count the frequency of each word in the string.

    Solution:

      def word_frequency(text):
          words = text.split()
          frequency = {}
          for word in words:
              if word in frequency:
                  frequency[word] += 1
              else:
                  frequency[word] = 1
          return frequency
    
      text = "this is a test this is only a test"
      print(word_frequency(text))
    

    Problem 2: Finding the Intersection of Two Lists

    Problem: Given two lists, find the common elements.

    Solution:

      def intersection(list1, list2):
          set1 = set(list1)
          set2 = set(list2)
          return list(set1.intersection(set2))
    
      list1 = [1, 2, 3, 4, 5]
      list2 = [4, 5, 6, 7, 8]
      print(intersection(list1, list2))  # Output: [4, 5]
    

    Problem 3: Finding Anagrams in a List of Words

    Problem: Given a list of words, group the anagrams together.

    Solution:

      def group_anagrams(words):
          anagrams = {}
          for word in words:
              sorted_word = ''.join(sorted(word))
              if sorted_word in anagrams:
                  anagrams[sorted_word].append(word)
              else:
                  anagrams[sorted_word] = [word]
          return list(anagrams.values())
    
      words = ["eat", "tea", "tan", "ate", "nat", "bat"]
      print(group_anagrams(words))
    

    Problem 4: Two Sum Problem

    Problem: Given an array of integers, return indices of the two numbers such that they add up to a specific target.

    Solution:

      def two_sum(nums, target):
          num_map = {}
          for i, num in enumerate(nums):
              complement = target - num
              if complement in num_map:
                  return [num_map[complement], i]
              num_map[num] = i
    
      nums = [2, 7, 11, 15]
      target = 9
      print(two_sum(nums, target))  # Output: [0, 1]
    

    Problem 5: Check if All Elements are Unique

    Problem: Determine if a list has all unique elements.

    Solution:

      def all_unique(lst):
          return len(lst) == len(set(lst))
    
      lst = [1, 2, 3, 4, 5]
      print(all_unique(lst))  # Output: True
    
      lst = [1, 2, 3, 4, 5, 1]
      print(all_unique(lst))  # Output: False
    

    Problem 6: Longest Substring Without Repeating Characters

    Problem: Given a string, find the length of the longest substring without repeating characters.

    Solution:

      def longest_unique_substring(s):
          char_map = {}
          left = 0
          max_length = 0
    
          for right, char in enumerate(s):
              if char in char_map and char_map[char] >= left:
                  left = char_map[char] + 1
              char_map[char] = right
              max_length = max(max_length, right - left + 1)
    
          return max_length
    
      s = "abcabcbb"
      print(longest_unique_substring(s))  # Output: 3 ("abc")
    

    Problem 7: Find the Difference Between Two Lists

    Problem: Given two lists, find the elements that are in the first list but not in the second.

    Solution:

      def difference(list1, list2):
          set1 = set(list1)
          set2 = set(list2)
          return list(set1.difference(set2))
    
      list1 = [1, 2, 3, 4, 5]
      list2 = [4, 5, 6, 7, 8]
      print(difference(list1, list2))  # Output: [1, 2, 3]
    

    Problem 8: Valid Parentheses

    Problem: Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid.

    Solution:

      def is_valid_parentheses(s):
          stack = []
          mapping = {')': '(', '}': '{', ']': '['}
    
          for char in s:
              if char in mapping:
                  top_element = stack.pop() if stack else '#'
                  if mapping[char] != top_element:
                      return False
              else:
                  stack.append(char)
    
          return not stack
    
      s = "()[]{}"
      print(is_valid_parentheses(s))  # Output: True
    
      s = "(]"
      print(is_valid_parentheses(s))  # Output: False
    

    Problem 9: Count the Number of Distinct Elements in a List

    Problem: Count the number of distinct elements in a list.

    Solution:

      def count_distinct_elements(lst):
          return len(set(lst))
    
      lst = [1, 2, 2, 3, 4, 4, 5]
      print(count_distinct_elements(lst))  # Output: 5
    

    Problem 10: Checking for Subset

    Problem: Check if one list is a subset of another.

    Solution:

      def is_subset(list1, list2):
          set1 = set(list1)
          set2 = set(list2)
          return set1.issubset(set2)
    
      list1 = [1, 2, 3]
      list2 = [1, 2, 3, 4, 5]
      print(is_subset(list1, list2))  # Output: True
    
      list1 = [1, 2, 6]
      print(is_subset(list1, list2))  # Output: False
    

    These problems cover a range of operations and algorithms involving dictionaries (hash maps) and sets, which are fundamental for efficiently solving many interview questions.Sure, let's explore solving problems using dictionaries (hash maps) and sets in Python. Dictionaries and sets are powerful tools that can be leveraged to solve various algorithmic problems efficiently.

    Problem 1: Word Frequency Count

    Problem: Given a string, count the frequency of each word in the string.

    Solution:

      def word_frequency(text):
          words = text.split()
          frequency = {}
          for word in words:
              if word in frequency:
                  frequency[word] += 1
              else:
                  frequency[word] = 1
          return frequency
    
      text = "this is a test this is only a test"
      print(word_frequency(text))
    

    Problem 2: Finding the Intersection of Two Lists

    Problem: Given two lists, find the common elements.

    Solution:

      def intersection(list1, list2):
          set1 = set(list1)
          set2 = set(list2)
          return list(set1.intersection(set2))
    
      list1 = [1, 2, 3, 4, 5]
      list2 = [4, 5, 6, 7, 8]
      print(intersection(list1, list2))  # Output: [4, 5]
    

    Problem 3: Finding Anagrams in a List of Words

    Problem: Given a list of words, group the anagrams together.

    Solution:

      def group_anagrams(words):
          anagrams = {}
          for word in words:
              sorted_word = ''.join(sorted(word))
              if sorted_word in anagrams:
                  anagrams[sorted_word].append(word)
              else:
                  anagrams[sorted_word] = [word]
          return list(anagrams.values())
    
      words = ["eat", "tea", "tan", "ate", "nat", "bat"]
      print(group_anagrams(words))
    

    Problem 4: Two Sum Problem

    Problem: Given an array of integers, return indices of the two numbers such that they add up to a specific target.

    Solution:

      def two_sum(nums, target):
          num_map = {}
          for i, num in enumerate(nums):
              complement = target - num
              if complement in num_map:
                  return [num_map[complement], i]
              num_map[num] = i
    
      nums = [2, 7, 11, 15]
      target = 9
      print(two_sum(nums, target))  # Output: [0, 1]
    

    Problem 5: Check if All Elements are Unique

    Problem: Determine if a list has all unique elements.

    Solution:

      def all_unique(lst):
          return len(lst) == len(set(lst))
    
      lst = [1, 2, 3, 4, 5]
      print(all_unique(lst))  # Output: True
    
      lst = [1, 2, 3, 4, 5, 1]
      print(all_unique(lst))  # Output: False
    

    Problem 6: Longest Substring Without Repeating Characters

    Problem: Given a string, find the length of the longest substring without repeating characters.

    Solution:

      def longest_unique_substring(s):
          char_map = {}
          left = 0
          max_length = 0
    
          for right, char in enumerate(s):
              if char in char_map and char_map[char] >= left:
                  left = char_map[char] + 1
              char_map[char] = right
              max_length = max(max_length, right - left + 1)
    
          return max_length
    
      s = "abcabcbb"
      print(longest_unique_substring(s))  # Output: 3 ("abc")
    

    Problem 7: Find the Difference Between Two Lists

    Problem: Given two lists, find the elements that are in the first list but not in the second.

    Solution:

      def difference(list1, list2):
          set1 = set(list1)
          set2 = set(list2)
          return list(set1.difference(set2))
    
      list1 = [1, 2, 3, 4, 5]
      list2 = [4, 5, 6, 7, 8]
      print(difference(list1, list2))  # Output: [1, 2, 3]
    

    Problem 8: Valid Parentheses

    Problem: Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid.

    Solution:

      def is_valid_parentheses(s):
          stack = []
          mapping = {')': '(', '}': '{', ']': '['}
    
          for char in s:
              if char in mapping:
                  top_element = stack.pop() if stack else '#'
                  if mapping[char] != top_element:
                      return False
              else:
                  stack.append(char)
    
          return not stack
    
      s = "()[]{}"
      print(is_valid_parentheses(s))  # Output: True
    
      s = "(]"
      print(is_valid_parentheses(s))  # Output: False
    

    Problem 9: Count the Number of Distinct Elements in a List

    Problem: Count the number of distinct elements in a list.

    Solution:

      def count_distinct_elements(lst):
          return len(set(lst))
    
      lst = [1, 2, 2, 3, 4, 4, 5]
      print(count_distinct_elements(lst))  # Output: 5
    

    Problem 10: Checking for Subset

    Problem: Check if one list is a subset of another.

    Solution:

      def is_subset(list1, list2):
          set1 = set(list1)
          set2 = set(list2)
          return set1.issubset(set2)
    
      list1 = [1, 2, 3]
      list2 = [1, 2, 3, 4, 5]
      print(is_subset(list1, list2))  # Output: True
    
      list1 = [1, 2, 6]
      print(is_subset(list1, list2))  # Output: False
    

    These problems cover a range of operations and algorithms involving dictionaries (hash maps) and sets, which are fundamental for efficiently solving many interview questions.Sure, let's explore solving problems using dictionaries (hash maps) and sets in Python. Dictionaries and sets are powerful tools that can be leveraged to solve various algorithmic problems efficiently.

    Problem 1: Word Frequency Count

    Problem: Given a string, count the frequency of each word in the string.

    Solution:

      def word_frequency(text):
          words = text.split()
          frequency = {}
          for word in words:
              if word in frequency:
                  frequency[word] += 1
              else:
                  frequency[word] = 1
          return frequency
    
      text = "this is a test this is only a test"
      print(word_frequency(text))
    

    Problem 2: Finding the Intersection of Two Lists

    Problem: Given two lists, find the common elements.

    Solution:

      def intersection(list1, list2):
          set1 = set(list1)
          set2 = set(list2)
          return list(set1.intersection(set2))
    
      list1 = [1, 2, 3, 4, 5]
      list2 = [4, 5, 6, 7, 8]
      print(intersection(list1, list2))  # Output: [4, 5]
    

    Problem 3: Finding Anagrams in a List of Words

    Problem: Given a list of words, group the anagrams together.

    Solution:

      def group_anagrams(words):
          anagrams = {}
          for word in words:
              sorted_word = ''.join(sorted(word))
              if sorted_word in anagrams:
                  anagrams[sorted_word].append(word)
              else:
                  anagrams[sorted_word] = [word]
          return list(anagrams.values())
    
      words = ["eat", "tea", "tan", "ate", "nat", "bat"]
      print(group_anagrams(words))
    

    Problem 4: Two Sum Problem

    Problem: Given an array of integers, return indices of the two numbers such that they add up to a specific target.

    Solution:

      def two_sum(nums, target):
          num_map = {}
          for i, num in enumerate(nums):
              complement = target - num
              if complement in num_map:
                  return [num_map[complement], i]
              num_map[num] = i
    
      nums = [2, 7, 11, 15]
      target = 9
      print(two_sum(nums, target))  # Output: [0, 1]
    

    Problem 5: Check if All Elements are Unique

    Problem: Determine if a list has all unique elements.

    Solution:

      def all_unique(lst):
          return len(lst) == len(set(lst))
    
      lst = [1, 2, 3, 4, 5]
      print(all_unique(lst))  # Output: True
    
      lst = [1, 2, 3, 4, 5, 1]
      print(all_unique(lst))  # Output: False
    

    Problem 6: Longest Substring Without Repeating Characters

    Problem: Given a string, find the length of the longest substring without repeating characters.

    Solution:

      def longest_unique_substring(s):
          char_map = {}
          left = 0
          max_length = 0
    
          for right, char in enumerate(s):
              if char in char_map and char_map[char] >= left:
                  left = char_map[char] + 1
              char_map[char] = right
              max_length = max(max_length, right - left + 1)
    
          return max_length
    
      s = "abcabcbb"
      print(longest_unique_substring(s))  # Output: 3 ("abc")
    

    Problem 7: Find the Difference Between Two Lists

    Problem: Given two lists, find the elements that are in the first list but not in the second.

    Solution:

      def difference(list1, list2):
          set1 = set(list1)
          set2 = set(list2)
          return list(set1.difference(set2))
    
      list1 = [1, 2, 3, 4, 5]
      list2 = [4, 5, 6, 7, 8]
      print(difference(list1, list2))  # Output: [1, 2, 3]
    

    Problem 8: Valid Parentheses

    Problem: Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid.

    Solution:

      def is_valid_parentheses(s):
          stack = []
          mapping = {')': '(', '}': '{', ']': '['}
    
          for char in s:
              if char in mapping:
                  top_element = stack.pop() if stack else '#'
                  if mapping[char] != top_element:
                      return False
              else:
                  stack.append(char)
    
          return not stack
    
      s = "()[]{}"
      print(is_valid_parentheses(s))  # Output: True
    
      s = "(]"
      print(is_valid_parentheses(s))  # Output: False
    

    Problem 9: Count the Number of Distinct Elements in a List

    Problem: Count the number of distinct elements in a list.

    Solution:

      def count_distinct_elements(lst):
          return len(set(lst))
    
      lst = [1, 2, 2, 3, 4, 4, 5]
      print(count_distinct_elements(lst))  # Output: 5
    

    Problem 10: Checking for Subset

    Problem: Check if one list is a subset of another.

    Solution:

      def is_subset(list1, list2):
          set1 = set(list1)
          set2 = set(list2)
          return set1.issubset(set2)
    
      list1 = [1, 2, 3]
      list2 = [1, 2, 3, 4, 5]
      print(is_subset(list1, list2))  # Output: True
    
      list1 = [1, 2, 6]
      print(is_subset(list1, list2))  # Output: False
    

    These problems cover a range of operations and algorithms involving dictionaries (hash maps) and sets, which are fundamental for efficiently solving many interview questions.Sure, let's explore solving problems using dictionaries (hash maps) and sets in Python. Dictionaries and sets are powerful tools that can be leveraged to solve various algorithmic problems efficiently.

    Problem 1: Word Frequency Count

    Problem: Given a string, count the frequency of each word in the string.

    Solution:

      def word_frequency(text):
          words = text.split()
          frequency = {}
          for word in words:
              if word in frequency:
                  frequency[word] += 1
              else:
                  frequency[word] = 1
          return frequency
    
      text = "this is a test this is only a test"
      print(word_frequency(text))
    

    Problem 2: Finding the Intersection of Two Lists

    Problem: Given two lists, find the common elements.

    Solution:

      def intersection(list1, list2):
          set1 = set(list1)
          set2 = set(list2)
          return list(set1.intersection(set2))
    
      list1 = [1, 2, 3, 4, 5]
      list2 = [4, 5, 6, 7, 8]
      print(intersection(list1, list2))  # Output: [4, 5]
    

    Problem 3: Finding Anagrams in a List of Words

    Problem: Given a list of words, group the anagrams together.

    Solution:

      def group_anagrams(words):
          anagrams = {}
          for word in words:
              sorted_word = ''.join(sorted(word))
              if sorted_word in anagrams:
                  anagrams[sorted_word].append(word)
              else:
                  anagrams[sorted_word] = [word]
          return list(anagrams.values())
    
      words = ["eat", "tea", "tan", "ate", "nat", "bat"]
      print(group_anagrams(words))
    

    Problem 4: Two Sum Problem

    Problem: Given an array of integers, return indices of the two numbers such that they add up to a specific target.

    Solution:

      def two_sum(nums, target):
          num_map = {}
          for i, num in enumerate(nums):
              complement = target - num
              if complement in num_map:
                  return [num_map[complement], i]
              num_map[num] = i
    
      nums = [2, 7, 11, 15]
      target = 9
      print(two_sum(nums, target))  # Output: [0, 1]
    

    Problem 5: Check if All Elements are Unique

    Problem: Determine if a list has all unique elements.

    Solution:

      def all_unique(lst):
          return len(lst) == len(set(lst))
    
      lst = [1, 2, 3, 4, 5]
      print(all_unique(lst))  # Output: True
    
      lst = [1, 2, 3, 4, 5, 1]
      print(all_unique(lst))  # Output: False
    

    Problem 6: Longest Substring Without Repeating Characters

    Problem: Given a string, find the length of the longest substring without repeating characters.

    Solution:

      def longest_unique_substring(s):
          char_map = {}
          left = 0
          max_length = 0
    
          for right, char in enumerate(s):
              if char in char_map and char_map[char] >= left:
                  left = char_map[char] + 1
              char_map[char] = right
              max_length = max(max_length, right - left + 1)
    
          return max_length
    
      s = "abcabcbb"
      print(longest_unique_substring(s))  # Output: 3 ("abc")
    

    Problem 7: Find the Difference Between Two Lists

    Problem: Given two lists, find the elements that are in the first list but not in the second.

    Solution:

      def difference(list1, list2):
          set1 = set(list1)
          set2 = set(list2)
          return list(set1.difference(set2))
    
      list1 = [1, 2, 3, 4, 5]
      list2 = [4, 5, 6, 7, 8]
      print(difference(list1, list2))  # Output: [1, 2, 3]
    

    Problem 8: Valid Parentheses

    Problem: Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid.

    Solution:

      def is_valid_parentheses(s):
          stack = []
          mapping = {')': '(', '}': '{', ']': '['}
    
          for char in s:
              if char in mapping:
                  top_element = stack.pop() if stack else '#'
                  if mapping[char] != top_element:
                      return False
              else:
                  stack.append(char)
    
          return not stack
    
      s = "()[]{}"
      print(is_valid_parentheses(s))  # Output: True
    
      s = "(]"
      print(is_valid_parentheses(s))  # Output: False
    

    Problem 9: Count the Number of Distinct Elements in a List

    Problem: Count the number of distinct elements in a list.

    Solution:

      def count_distinct_elements(lst):
          return len(set(lst))
    
      lst = [1, 2, 2, 3, 4, 4, 5]
      print(count_distinct_elements(lst))  # Output: 5
    

    Problem 10: Checking for Subset

    Problem: Check if one list is a subset of another.

    Solution:

      def is_subset(list1, list2):
          set1 = set(list1)
          set2 = set(list2)
          return set1.issubset(set2)
    
      list1 = [1, 2, 3]
      list2 = [1, 2, 3, 4, 5]
      print(is_subset(list1, list2))  # Output: True
    
      list1 = [1, 2, 6]
      print(is_subset(list1, list2))  # Output: False
    

    These problems cover a range of operations and algorithms involving dictionaries (hash maps) and sets, which are fundamental for efficiently solving many interview questions.