def print_columns(objects, cols=3, gap=2):
    """ Print a list of items in rows and columns """

    # if the list is empty, do nothing
    if not objects:
        return ""

    # make sure we have a string for each item in the list
    str_list = [str(x) for x in objects]

    # can't have more columns than items
    if cols > len(str_list):
        cols = len(str_list)

    max_length = max([len(x) for x in str_list])

    # get a list of lists which each represent a row in the output
    row_list = [str_list[i:i+cols] for i in range(0, len(str_list), cols)]

    # join together each row in the output with a newline
    # left justify each item in the list according to the longest item
    output = '\n'.join([
        ''.join([x.ljust(max_length + gap) for x in row_item])
        for row_item in row_list
    ])

    return output