1

I was wondering how to find the second smallest number from a user-input list with def functions. Also, WITHOUT using any sorting functions, imported modules, and min() and max() functions, how would I find the numbers by using just loops and relational operators?

Here's my following code (I only have finding the smallest number so far...):

def second_smallest():
    smallest = second_smallest[0]
    for i in second_smallest[1:]:
        if smallest > i:
            smallest = i
    return smallest

Examples of following tests are shown:

print(second_smallest([5, 7, 2, 1, 3]))
2
print(second_smallest([100, 51, 31, 5, 10]))
10

Thanks!

DaveNOTDavid
  • 1,753
  • 5
  • 19
  • 37
  • 3
    `second_smallest` is both a function and a list? I guess you need to edit your code sample in the question. – Bhargav Rao Sep 28 '15 at 18:08
  • Yes. That will cause some problems for you. – Mad Physicist Sep 28 '15 at 18:12
  • 3
    What is the expected output of `print(second_smallest([-1, 1, 2, 3, 0, -1]))`. Is it `-1` or `0`? – Mad Physicist Sep 28 '15 at 18:13
  • 2
    For people who find this who aren't asking SO to do their homework, the correct answer is: [`heapq.nsmallest(2, mylist)[1]`](https://docs.python.org/3/library/heapq.html#heapq.nsmallest) (Note: This will raise an `IndexError` if the list in question is less than two elements long, handling that would be dependent on desired behavior) – ShadowRanger Sep 28 '15 at 19:32

2 Answers2

1
>>> def second_smallest(lst):
...     first = second = float("inf")
...     for num in lst:
...         if num < first:
...             second, first = first, num
...         elif first < num < second:
...             second = num
...     return second

Please note that this returns float('inf') (initial value) for lists with len(lst) <= 1 as there is no second item in the list.

Ozgur Vatansever
  • 49,246
  • 17
  • 84
  • 119
0

SO Isn't really for homework, but it sounds like you have had a think about this. There are two situations to consider and both require knowledge of the smallest:

  1. the second smallest is seen before the smallest is seen, in which case the second smallest will be the value that smallest held before it held its final value.
  2. The second smallest is seen after the smallest is seen, in which case the second smallest will be bigger than it, but smallest won't be smaller than it OR equal to it

I've expressed this in the code below. We've had to keep the existing smallest tracking and add to it.

def second_smallest():
    smallest = float("inf")
    second_smallest = float("inf")
    for i in second_smallest:
        if smallest > i:
            second_smallest = smallest
            smallest = i
        elif second_smallest > i and not smallest == i:
            second_smallest = i
    return second_smallest

Note, technically there might not be a second smallest, if you provide a list of the same numbers. e.g. [4,4,4,4]. The code above will return 4, but really, it's an error case that should be considered and dealt with.

This is a simple approach that would break down for a question like "what is the nth smallest?" At which point you have basically created a sorting algorithm.

Sam
  • 3,453
  • 1
  • 33
  • 57