M3) Replacing negative tuple values

A measurement tuple contains integers. zero_negatives(values) must return a tuple with the same length and order, replacing each negative value with 0 and retaining every other value. The input tuple must remain unchanged.

For values = (1, -2, 3, -4, 5), the required result is (1, 0, 3, 0, 5). Empty input must return ().

Compare the four implementations in Listing 1.

Listing 1: Four ways to construct a tuple with negative measurements replaced by zero.
(a) Alternative A.
def zero_negatives(values):
    result = []
    for value in values:
        if value < 0:
            result.append(0)
        else:
            result.append(value)
    return tuple(result)
(b) Alternative B.
def zero_negatives(values):
    result = [0] * len(values)
    for i in range(len(values)):
        if values[i] < 0:
            values[i] = 0
    return tuple(result)
(c) Alternative C.
def zero_negatives(values):
    result = []
    size = len(result)
    result = [0] * len(values)
    for i in range(size):
        if values[i] < 0:
            result[i] = 0
        else:
            result[i] = values[i]
    return tuple(result)
(d) Alternative D.
def zero_negatives(values):
    result = [0] * len(values)
    for i in range(len(values)):
        if values[i] < 0:
            result[i] = 0
    return tuple(result)

Which implementation satisfies the stated requirements?

  • len(values) returns the number of items.
  • range(stop) visits integers from 0 up to, but excluding, stop: list(range(2)) is [0, 1]. list collects values into a new list, and range(0) is empty.
  • result.append(value) adds one value to the end of the list and returns None; appending 6 to [4] changes it to [4, 6].
  • tuple(result) creates a tuple containing the list’s items in order: tuple([4, 6]) is (4, 6).