# Lists, sets, and maps ​

## Lists ​

A list of elements of type `t` has type `sp.list[t]`. For example, `[1, 2, 3]` has type `sp.list[sp.int]`.

smartpy
``````len(x: sp.list[t]) -> sp.nat
``````

Returns the length of a list, e.g. `len(["a", "b", "c"]) == 3`.

smartpy
``````sp.sum(xs: sp.list[sp.int]) -> sp.int
sp.sum(xs: sp.list[sp.nat]) -> sp.nat
``````

Returns the sum of all the elements in a list, e.g. `sp.sum([1, 2, 3]) == 6`. Works on lists of both `sp.nat` and `sp.int`.

smartpy
``````sp.cons(x: t, x: sp.list[t]) -> sp.list[t]
``````

Returns a new list with an element added to the front. For example `sp.cons(1, [2, 3])` evaluates to `[1, 2, 3]`.

smartpy
``````sp.range(to: sp.nat) -> sp.list[sp.nat]
sp.range(to: sp.int) -> sp.list[sp.int]
sp.range(from_: sp.nat, to: sp.nat) -> sp.list[sp.nat]
sp.range(from_: sp.int, to: sp.int) -> sp.list[sp.int]
sp.range(from_: sp.nat, to: sp.nat, step: sp.nat) -> sp.list[sp.nat]
sp.range(from_: sp.int, to: sp.int, step: sp.int) -> sp.list[sp.int]
``````

`sp.range(3)` evaluates to `[0, 1, 2]`.

`sp.range(3, 7)` evaluates to `[3, 4, 5, 6]`.

`sp.range(3, 7, 2)` evaluates to `[3, 5]`.

## Sets ​

A set of elements of type `t` has type `sp.set[t]`. For example, `sp.set(1, 2, 3)` has type `sp.set[sp.int]`.

smartpy
``````len(x: sp.set[t]) -> sp.nat
``````

Returns the number of elements in a set.

smartpy
``````s.contains(x: t) -> sp.bool
``````

For a set `m` of type `sp.set[t]`, returns a boolean value indicating whether `x` is an element of `s`.

smartpy
``````s.elements() -> sp.list[t]
``````

For a set `s` of type `sp.set[t]` returns its elements as a list.

smartpy
``````s.add(x: t)
``````

Adds an element to a set. For example:

smartpy
``````s = sp.set(1, 2, 3)
assert s.contains(4)
``````

## Maps ​

A map that takes elements of type `k` to elements of type `v` has type `sp.map[k, v]`. SmartPy maps are similar to Python's dictionaries. `sp.map({'a': 65}, {'b': 66})`.

An entry can be looked up with the `m[...]` notation, e.g.:

smartpy
``````m = {'a': 65, 'b': 66}
assert m['a'] == 65
``````

An entry can be deleted from a map using the statement `del m[key]`. For example:

smartpy
``````m = {'a': 65, 'b': 66}
del m['a']
assert not m.contains('a')
``````

smartpy
``````m.get(key, default=...)
m.get(key, error=...)
``````

Looks up `key` in the map `m`. If `key` does not have an entry in the map, `default` is returned or `error` is raised, according to which keyword argument is given.

smartpy
``````len(x: sp.map[k, v]) -> sp.nat
``````

Returns the size of a map, i.e. the number of its entries.

smartpy
``````m.items() -> sp.list[sp.record(key=k, value=v)]
``````

`{'a': 97, 'b': 98}.items()` evaluates to `[sp.record(key='a', value=97), sp.record(key='b', value=98)]`.

smartpy
``````m.keys() -> sp.list[k]
``````

`{'a': 97, 'b': 98}.keys()` evaluates to `['a', 'b']`.

smartpy
``````m.values() -> sp.list[v]
``````

`{'a': 97, 'b': 98}.values()` evaluates to `[97, 98]`.

smartpy
``````sp.update_map(key: k, value: sp.option[v], m: map[k, v]) -> map[k, v]
``````

Returns a copy of `m` with a modified entry at `key`: if `value == None`, it is removed; if `value == sp.Some(v)`, it is `v`.

Example:

smartpy
``````assert sp.update_map('a', sp.Some(3), {})['a'] == 3
assert sp.update_map('a', None, {'a': 2}).get('a', default=-1) == -1
``````

## Big maps ​

Analogous to `sp.map` there is `sp.big_map[k, v]`, denoting lazily deserialized maps from `k` to `v`. These maps should be used if you intend to store large amounts of data in a map. Using `sp.big_map` can reduce gas costs significantly compared to standard maps, as data is lazily deserialized. Note however that individual operations on `sp.big_map` have higher gas costs than those over standard maps. A `sp.big_map` also has a lower storage cost than a standard map of the same size, when large keys are used, since only the hash of each key is stored in a `sp.big_map`.

A `sp.big_map` cannot be iterated over, nor contained in another big map.