code: def nsmallest(n, iterable, key=None):
      
  
      # Short-cut for n==1 is to use min()
      if n == 1:
          it = iter(iterable)
          sentinel = object()
          if key is None:
              result = min(it, default=sentinel)
          else:
              result = min(it, default=sentinel, key=key)
          return [] if result is sentinel else [result]
  
      # When n>=size, it's faster to use sorted()
      try:
          size = len(iterable)
      except (TypeError, AttributeError):
          pass
      else:
          if n >= size:
              return sorted(iterable, key=key)[:n]
  
      # When key is none, use simpler decoration
      if key is None:
          it = iter(iterable)
          # put the range(n) first so that zip() doesn't
          # consume one too many elements from the iterator
          result = [(elem, i) for i, elem in zip(range(n), it)]
          if not result:
              return result
          _heapify_max(result)
          top = result[0][0]
          order = n
          _heapreplace = _heapreplace_max
          for elem in it:
              if elem < top:
                  _heapreplace(result, (elem, order))
                  top = result[0][0]
                  order += 1
          result.sort()
          return [r[0] for r in result]
  
      # General case, slowest method
      it = iter(iterable)
      result = [(key(elem), i, elem) for i, elem in zip(range(n), it)]
      if not result:
          return result
      _heapify_max(result)
      top = result[0][0]
      order = n
      _heapreplace = _heapreplace_max
      for elem in it:
          k = key(elem)
          if k < top:
              _heapreplace(result, (k, order, elem))
              top = result[0][0]
              order += 1
      result.sort()
      return [r[2] for r in result]
docs: Find the n smallest elements in a dataset.
  
      Equivalent to:  sorted(iterable, key=key)[:n]