<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def list(gandi, datacenter, type, id, attached, detached, version, reverse, vm, vlan):
 """List ips."""

    if attached and detached:
        gandi.echo("You can't set --attached and --detached at the same time.")
        return

    output_keys = ['ip', 'state', 'dc', 'type']
    if id:
        output_keys.append('id')
    if version:
        output_keys.append('version')
    if vm:
        output_keys.append('vm')
    if reverse:
        output_keys.append('reverse')

    options = {}
    opt_dc = {}
    if datacenter:
        datacenter_id = int(gandi.datacenter.usable_id(datacenter))
        options['datacenter_id'] = datacenter_id
        opt_dc = {'datacenter_id': datacenter_id}

    iface_options = {}
    if type:
        iface_options['type'] = type
    if vlan:
        iface_options['vlan'] = vlan
    if attached:
        iface_options['state'] = 'used'
    elif detached:
        iface_options['state'] = 'free'

    if iface_options:
        ifaces = gandi.iface.list(iface_options)
        options['iface_id'] = [iface['id'] for iface in ifaces]
    iface_options.update(opt_dc)

    datacenters = gandi.datacenter.list()

    ips = gandi.ip.list(options)
    ifaces = dict([(iface['id'], iface)
                   for iface in gandi.iface.list(iface_options)])
    vms = dict([(vm_['id'], vm_)
                for vm_ in gandi.iaas.list(opt_dc)])

    for num, ip_ in enumerate(ips):
        if num:
            gandi.separator_line()
        output_ip(gandi, ip_, datacenters, vms, ifaces, output_keys)

    return ips