<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def join(left, right, on=None, how='inner', suffixes=('_x', '_y'), mapjoin=False):
 """ Join two collections. If `on` is not specified, we will find the common fields of the left and right collection. `suffixes` means that if column names conflict, the suffixes will be added automatically. For example, both left and right has a field named `col`, there will be col_x, and col_y in the joined collection. :param left: left collection :param right: right collection :param on: fields to join on :param how: 'inner', 'left', 'right', or 'outer' :param suffixes: when name conflict, the suffix will be added to both columns. :param mapjoin: set use mapjoin or not, default value False. :return: collection :Example: ['name', 'id'] ['name', 'id1'] """

    if on is None and not mapjoin:
        on = [name for name in left.schema.names if name in right.schema._name_indexes]

    if isinstance(suffixes, (tuple, list)) and len(suffixes) == 2:
        left_suffix, right_suffix = suffixes
    else:
        raise ValueError('suffixes must be a tuple or list with two elements, got %s' % suffixes)
    if not isinstance(on, list):
        on = [on, ]
    for i in range(len(on)):
        it = on[i]
        if inspect.isfunction(it):
            on[i] = it(left, right)

    left, right = _make_different_sources(left, right, on)

    try:
        return _join_dict[how.upper()](_lhs=left, _rhs=right, _predicate=on, _left_suffix=left_suffix,
                                       _right_suffix=right_suffix, _mapjoin=mapjoin)
    except KeyError:
        return JoinCollectionExpr(_lhs=left, _rhs=right, _predicate=on, _how=how, _left_suffix=left_suffix,
                                  _right_suffix=right_suffix, _mapjoin=mapjoin)