Understanding Lists, sets and tuples in Python.
Tags: beginners, programming, datastructure, python
Published: 2023-05-28 01:09:11


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ai679oti6ltqufs4vq53.png)
Lists are one of the most commonly used data structures in Python. They are used to store collections of data, Such as a list of numbers or a list of names. In this article, we will explore the basics of list in Python and learn how to work with them.


## Creating a collection

We will start with collections: a collection is a single variable used to store multiple values.

```
#Collection = single "variable" used to store multiple values
# List = [] ordered and changeable. Duplicates OK.
# Set = {} unordered and immutable but Add/Remove OK. No duplicates.
# Tuple = () ordered and unchangeable. Duplicates OK. Faster

fruits = ["apple", "orange", "banana", "coconut"]

print(fruits)
```
The collection of fruits that is created above will give you the following output.

```
['apple', 'orange', 'banana', 'coconut']
```
To access the elements that is found within your collection, you can use the index operator. Unlike we do with strings, the first element has an index of [0]. Considering the example below.

```
fruits = ["apple", "orange", "banana", "coconut"]

print(fruits[0])
```
The output will be:

```
apple
```
Because it the first element of the collection with an index of `[0]`. The same goes for all of the list element if we change the index from `[0]` to `[2]`, we have banana as our output.

```
fruits = ["apple", "orange", "banana", "coconut"]

print(fruits[2])
```
Output:

```
banana
```
With `indexes`, you could set the range of the output you would like to have. For example.

```
fruits = ["apple", "orange", "banana", "coconut"]

print(fruits[0:3])
```
It gives you the output.

```
['apple', 'orange', 'banana']
```
Also, you can change your `indexes` the way you want to give you the output you want. For example.

```
fruits = ["apple", "orange", "banana", "coconut"]

print(fruits[::2])
```
You can also iterate through your collection using a `for loop`.
```
fruits = ["apple", "orange", "banana", "coconut"]

# print(fruits[0])

for x in fruits:
    print(x)
```
Will give the output:

```
apple
orange
banana
coconut
```
or for a better understanding you can change x to anything that will be easy for you to understand and print it out.

There are some functions we can also use to manipulate our collections.

```
fruits = ["apple", "orange", "banana", "coconut"]
print(dir(fruits))
# print(fruits[0])

# for x in fruits:
#     print(x)
```
using the `dir()` function.

```
['__add__', '__class__', '__class_getitem__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

```
Also, we have a `help() `function which is used to describe a method.

```
Help on list object:

class list(object)
 |  list(iterable=(), /)
 |  
 |  Built-in mutable sequence.
 |  
 |  If no argument is given, the constructor creates a new empty list.
 |  The argument must be an iterable if specified.
 |  
 |  Methods defined here:
 |  
 |  __add__(self, value, /)
 |      Return self+value.
 |  
 |  __contains__(self, key, /)
 |      Return key in self.
 |  
 |  __delitem__(self, key, /)
 |      Delete self[key].
 |  
 |  __eq__(self, value, /)
 |      Return self==value.
 |  
 |  __ge__(self, value, /)
 |      Return self>=value.
 |  
 |  __getattribute__(self, name, /)
 |      Return getattr(self, name).
 |  
 |  __getitem__(...)
 |      x.__getitem__(y) <==> x[y]
 |  
 |  __gt__(self, value, /)
 |      Return self>value.
 |  
 |  __iadd__(self, value, /)
 |      Implement self+=value.
 |  
 |  __imul__(self, value, /)
 |      Implement self*=value.
 |  
 |  __init__(self, /, *args, **kwargs)
 |      Initialize self.  See help(type(self)) for accurate signature.
 |  
 |  __iter__(self, /)
 |      Implement iter(self).
 |  
 |  __le__(self, value, /)
 |      Return self<=value.
 |  
 |  __len__(self, /)
 |      Return len(self).
 |  
 |  __lt__(self, value, /)
 |      Return self<value.
 |  
 |  __mul__(self, value, /)
 |      Return self*value.
 |  
 |  __ne__(self, value, /)
 |      Return self!=value.
 |  
 |  __repr__(self, /)
 |      Return repr(self).
 |  
 |  __reversed__(self, /)
 |      Return a reverse iterator over the list.
 |  
 |  __rmul__(self, value, /)
 |      Return value*self.
 |  
 |  __setitem__(self, key, value, /)
 |      Set self[key] to value.
 |  
 |  __sizeof__(self, /)
 |      Return the size of the list in memory, in bytes.
 |  
 |  append(self, object, /)
 |      Append object to the end of the list.
 |  
 |  clear(self, /)
 |      Remove all items from list.
 |  
 |  copy(self, /)
 |      Return a shallow copy of the list.
 |  
 |  count(self, value, /)
 |      Return number of occurrences of value.
 |  
 |  extend(self, iterable, /)
 |      Extend list by appending elements from the iterable.
 |  
 |  index(self, value, start=0, stop=9223372036854775807, /)
 |      Return first index of value.
 |      
 |      Raises ValueError if the value is not present.
 |  
 |  insert(self, index, object, /)
 |      Insert object before index.
 |  
 |  pop(self, index=-1, /)
 |      Remove and return item at index (default last).
 |      
 |      Raises IndexError if list is empty or index is out of range.
 |  
 |  remove(self, value, /)
 |      Remove first occurrence of value.
 |      
 |      Raises ValueError if the value is not present.
 |  
 |  reverse(self, /)
 |      Reverse *IN PLACE*.
 |  
 |  sort(self, /, *, key=None, reverse=False)
 |      Sort the list in ascending order and return None.
 |      
 |      The sort is in-place (i.e. the list itself is modified) and stable (i.e. the
 |      order of two equal elements is maintained).
 |      
 |      If a key function is given, apply it once to each list item and sort them,
 |      ascending or descending, according to their function values.
 |      
 |      The reverse flag can be set to sort in descending order.
 |  
 |  ----------------------------------------------------------------------
 |  Class methods defined here:
 |  
 |  __class_getitem__(...) from builtins.type
 |      See PEP 585
 |  
 |  ----------------------------------------------------------------------
 |  Static methods defined here:
 |  
 |  __new__(*args, **kwargs) from builtins.type
 |      Create and return a new object.  See help(type) for accurate signature.
 |  
 |  ----------------------------------------------------------------------
 |  Data and other attributes defined here:
 |  
 |  __hash__ = None
```
If you need the length of the elements of your collection, you can use the `len()` function.

```
fruits = ["apple", "orange", "banana", "coconut"]
print(len(fruits))
```
will print the output:

```
4
```
Giving you the exact length of your collection.

Using the `“in”` operation we could find a value within our collection.

```
fruits = ["apple", "orange", "banana", "coconut"]
print("apple" in fruits)
```
will print true as an output because `apple` is within our collection.

```
true
```
Now what if you try an element which is not within our collection? For example, `pineapple`, it prints `false`. Because `pineapple` is not found within our collection.

## Creating a List.
A `list` in python is an `ordered` and `changeable` collection of data objects. Unlike arrays, which can contain a mixture of a single type, a list can contain a mixture of objects. With list they are `ordered` and `changeable`, and they `accept duplicates`.

We can change one of our values or elements after we create our list. For example:

```
fruits = ["apple", "orange", "banana", "coconut"]
fruits[0] = 'pineapple'
for x in fruits:
    print(x)
```
Results:

```
pineapple
orange
banana
coconut
```
You can see that our first element is no longer `apple`, it has been changed from `apple` to `pineapple`.

You can reassign the index by changing from `fruits[0]` to `fruits[2]` and `pineapple` will replace that element of the `index [2]` which is `banana`.

Let us cover Some of the methods that are found in a list. 
The first is `append()`.
```
fruits = ["apple", "orange", "banana", "coconut"]
fruits.append("pinapple")

print(fruits)
```
Will `add` `pineapple` at the end of our list of fruits. See the results below:

```
['apple', 'orange', 'banana', 'coconut', 'pinapple']
```
To remove an element in our list, we will use the `remove()` method.

```
fruits = ["apple", "orange", "banana", "coconut"]
fruits.remove("apple")

print(fruits)
```

```
Results:
['orange', 'banana', 'coconut', 'pinapple']
```
and apple has been removed from our list.

To insert and element in a list, you can use the `insert(index,“element”)` method. We can insert a value at a given index. For example:

```
fruits = ["apple", "orange", "banana", "coconut"]
fruits.insert(0,"pinapple")

print(fruits)
```
Will output:

```
['pineapple', 'apple', 'orange', 'banana', 'coconut']
```
putting `pineapple` at the first position which has an `index` of `0`.

Also, we have a `sort()` method, which is used to sort a list in alphabetical order.

```
fruits = ["apple", "orange", "banana", "coconut"]
fruits.sort()

print(fruits)
```
we have,

```
['apple', 'banana', 'coconut', 'orange']
```
Now we have our list in alphabetical order.

To reverse a list, you can use the `reverse()` method.

```
fruits = ["apple", "orange", "banana", "coconut"]
fruits.reverse()

print(fruits)
```
Output:

```
['coconut', 'banana', 'orange', 'apple']
```
We now have our list in a reversed order. However, these elements are not reversed in alphabetical order instead they are replaced in the way we placed them. If you want to reverse in alphabetical order, you can first `sort()` and then `reverse()`.

To clear all the elements of a list, you can use the `clear() `method.

```
fruits = ["apple", "orange", "banana", "coconut"]
fruits.clear()

print(fruits)
```
We can also return the index of a value or an element.

```
fruits = ["apple", "orange", "banana", "coconut"]
fruits.clear()

print(fruits.index("apple"))
print(fruits)
```
and we have our index returned:

```
0
['apple', 'orange', 'banana', 'coconut']
```
`Zero [0]` which is the index of `apple`.

We can count the amount of time a value is found within a list because duplicates are Ok.

```
fruits = ["apple","banana", "orange", "banana", "coconut"]
print(fruits.count("banana"))

print(fruits)
```
We can see that there are 2 bananas in the list:

```
2
['apple', 'banana','orange', 'banana', 'coconut']
```

## Creating sets.
Sets are `unordered` and` immutable`, but `Add/Remove` is ok. `No duplicates`.

To create a set, we use `{}` instead of `[]`.

```
fruits = {"apple", "orange", "banana", "coconut"}
print(fruits)
```
A set is unordered as we can see below.

```
{'orange', 'coconut', 'banana', 'apple'}
```
To display the all the attributes and methods of a set, you can use the `dir()` function.

```
fruits = {"apple", "orange", "banana", "coconut"}
print(dir(fruits))
```

```
['__and__', '__class__', '__class_getitem__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__iand__', '__init__', '__init_subclass__', '__ior__', '__isub__', '__iter__', '__ixor__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__or__', '__rand__', '__reduce__', '__reduce_ex__', '__repr__', '__ror__', '__rsub__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__xor__', 'add', 'clear', 'copy', 'difference', 'difference_update', 'discard', 'intersection', 'intersection_update', 'isdisjoint', 'issubset', 'issuperset', 'pop', 'remove', 'symmetric_difference', 'symmetric_difference_update', 'union', 'update']
{'apple', 'orange', 'coconut', 'banana'}
```
For an in-depth description of these methods, you can use the `help()` function.

```
class set(object)
 |  set() -> new empty set object
 |  set(iterable) -> new set object
 |  
 |  Build an unordered collection of unique elements.
 |  
 |  Methods defined here:
 |  
 |  __and__(self, value, /)
 |      Return self&value.
 |  
 |  __contains__(...)
 |      x.__contains__(y) <==> y in x.
 |  
 |  __eq__(self, value, /)
 |      Return self==value.
 |  
 |  __ge__(self, value, /)
 |      Return self>=value.
 |  
 |  __getattribute__(self, name, /)
 |      Return getattr(self, name).
 |  
 |  __gt__(self, value, /)
 |      Return self>value.
 |  
 |  __iand__(self, value, /)
 |      Return self&=value.
 |  
 |  __init__(self, /, *args, **kwargs)
 |      Initialize self.  See help(type(self)) for accurate signature.
 |  
 |  __ior__(self, value, /)
 |      Return self|=value.
 |  
 |  __isub__(self, value, /)
 |      Return self-=value.
 |  
 |  __iter__(self, /)
 |      Implement iter(self).
 |  
 |  __ixor__(self, value, /)
 |      Return self^=value.
 |  
 |  __le__(self, value, /)
 |      Return self<=value.
 |  
 |  __len__(self, /)
 |      Return len(self).
 |  
 |  __lt__(self, value, /)
 |      Return self<value.
 |  
 |  __ne__(self, value, /)
 |      Return self!=value.
 |  
 |  __or__(self, value, /)
 |      Return self|value.
 |  
 |  __rand__(self, value, /)
 |      Return value&self.
 |  
 |  __reduce__(...)
 |      Return state information for pickling.
 |  
 |  __repr__(self, /)
 |      Return repr(self).
 |  
 |  __ror__(self, value, /)
 |      Return value|self.
 |  
 |  __rsub__(self, value, /)
 |      Return value-self.
 |  
 |  __rxor__(self, value, /)
 |      Return value^self.
 |  
 |  __sizeof__(...)
 |      S.__sizeof__() -> size of S in memory, in bytes
 |  
 |  __sub__(self, value, /)
 |      Return self-value.
 |  
 |  __xor__(self, value, /)
 |      Return self^value.
 |  
 |  add(...)
 |      Add an element to a set.
 |      
 |      This has no effect if the element is already present.
 |  
 |  clear(...)
 |      Remove all elements from this set.
 |  
 |  copy(...)
 |      Return a shallow copy of a set.
 |  
 |  difference(...)
 |      Return the difference of two or more sets as a new set.
 |      
 |      (i.e. all elements that are in this set but not the others.)
 |  
 |  difference_update(...)
 |      Remove all elements of another set from this set.
 |  
 |  discard(...)
 |      Remove an element from a set if it is a member.
 |      
 |      If the element is not a member, do nothing.
 |  
 |  intersection(...)
 |      Return the intersection of two sets as a new set.
 |      
 |      (i.e. all elements that are in both sets.)
 |  
 |  intersection_update(...)
 |      Update a set with the intersection of itself and another.
 |  
 |  isdisjoint(...)
 |      Return True if two sets have a null intersection.
 |  
 |  issubset(...)
 |      Report whether another set contains this set.
 |  
 |  issuperset(...)
 |      Report whether this set contains another set.
 |  
 |  pop(...)
 |      Remove and return an arbitrary set element.
 |      Raises KeyError if the set is empty.
 |  
 |  remove(...)
 |      Remove an element from a set; it must be a member.
 |      
 |      If the element is not a member, raise a KeyError.
 |  
 |  symmetric_difference(...)
 |      Return the symmetric difference of two sets as a new set.
 |      
 |      (i.e. all elements that are in exactly one of the sets.)
 |  
 |  symmetric_difference_update(...)
 |      Update a set with the symmetric difference of itself and another.
 |  
 |  union(...)
 |      Return the union of sets as a new set.
 |      
 |      (i.e. all elements that are in either set.)
 |  
 |  update(...)
 |      Update a set with the union of itself and others.
 |  
 |  ----------------------------------------------------------------------
 |  Class methods defined here:
 |  
 |  __class_getitem__(...) from builtins.type
 |      See PEP 585
 |  
 |  ----------------------------------------------------------------------
 |  Static methods defined here:
 |  
 |  __new__(*args, **kwargs) from builtins.type
 |      Create and return a new object.  See help(type) for accurate signature.
 |  
 |  ----------------------------------------------------------------------
 |  Data and other attributes defined here:
 |  
 |  __hash__ = None
```
And the other functions are almost similar to those of a set. We can’t change a value of a set, but we could add or remove elements. Let’s use the `add()` method to add an element to our set.

```
fruits = {"apple", "orange", "banana", "coconut"}
print(fruits.add("mango"))
print(fruits)
```
To have:

```
None
{'mango', 'banana', 'apple', 'orange', 'coconut'}
```
and now `“mango”` is added to our set.

Also, we can remove an element using the `remove()` method.

```
fruits = {"apple", "orange", "banana", "coconut"}
print(fruits.remove("apple"))
print(fruits)
```
and now the `apple` is removed.

```
{'mango', 'banana','orange', 'coconut'}
```
The `pop()` method will remove the first value from the list.

```
fruits = {"apple", "orange", "banana", "coconut"}
fruits.pop()
print(fruits)
```

```
{'apple', 'banana', 'coconut'}
```
and the `clear()` method is used to clear all elements from the set.

```
fruits = {"apple", "orange", "banana", "coconut"}
fruits.clear()
print(fruits)
```
Now lastly let’s talk about tuples.

## Creating a tuple.
A `tuple` is created same as a set but `()` are used instead of `{}`, it is `ordered` and `unchangeable`. `Duplicates` OK, Faster (that is why is more preferable to use tuples than collections. So let us see the example below.

```
fruits = ("apple", "orange", "banana", "coconut")
print(fruits)
```
Results:
```
('apple', 'orange', 'banana', 'coconut')
```
and also, the `dir()` function is used to see its attributes and methods.

```
fruits = ("apple", "orange", "banana", "coconut")
print(dir(fruits))
print(fruits)
```

```
['__add__', '__class__', '__class_getitem__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'count', 'index']
('apple', 'orange', 'banana', 'coconut')
```
use the `help()` method to get more insight about these attributes.

```
fruits = ("apple", "orange", "banana", "coconut")
print(dir(fruits))
print(help(fruits)
```

```
class tuple(object)
 |  tuple(iterable=(), /)
 |  
 |  Built-in immutable sequence.
 |  
 |  If no argument is given, the constructor returns an empty tuple.
 |  If iterable is specified the tuple is initialized from iterable's items.
 |  
 |  If the argument is a tuple, the return value is the same object.
 |  
 |  Built-in subclasses:
 |      asyncgen_hooks
 |      UnraisableHookArgs
 |  
 |  Methods defined here:
 |  
 |  __add__(self, value, /)
 |      Return self+value.
 |  
 |  __contains__(self, key, /)
 |      Return key in self.
 |  
 |  __eq__(self, value, /)
 |      Return self==value.
 |  
 |  __ge__(self, value, /)
 |      Return self>=value.
 |  
 |  __getattribute__(self, name, /)
 |      Return getattr(self, name).
 |  
 |  __getitem__(self, key, /)
 |      Return self[key].
 |  
 |  __getnewargs__(self, /)
 |  
 |  __gt__(self, value, /)
 |      Return self>value.
 |  
 |  __hash__(self, /)
 |      Return hash(self).
 |  
 |  __iter__(self, /)
 |      Implement iter(self).
 |  
 |  __le__(self, value, /)
 |      Return self<=value.
 |  
 |  __len__(self, /)
 |      Return len(self).
 |  
 |  __lt__(self, value, /)
 |      Return self<value.
 |  
 |  __mul__(self, value, /)
 |      Return self*value.
 |  
 |  __ne__(self, value, /)
 |      Return self!=value.
 |  
 |  __repr__(self, /)
 |      Return repr(self).
 |  
 |  __rmul__(self, value, /)
 |      Return value*self.
 |  
 |  count(self, value, /)
 |      Return number of occurrences of value.
 |  
 |  index(self, value, start=0, stop=9223372036854775807, /)
 |      Return first index of value.
 |      
 |      Raises ValueError if the value is not present.
 |  
 |  ----------------------------------------------------------------------
 |  Class methods defined here:
 |  
 |  __class_getitem__(...) from builtins.type
 |      See PEP 585
 |  
 |  ----------------------------------------------------------------------
 |  Static methods defined here:
 |  
 |  __new__(*args, **kwargs) from builtins.type
 |      Create and return a new object.  See help(type) for accurate signature.

```
Use the `len() `function to find the length, the `“in”` method to check if value exist in tuple, the `index()` function to find the index, the `.count()` function to count the number of elements in the tuple.

```
fruits = ("apple", "orange","coconut" ,"banana", "coconut")
print(fruits.count("coconut"))
print(fruits)
```
Results:

```
2
('apple', 'orange', 'coconut', 'banana', 'coconut')
```
We can also use the `for loop` to iterate through our tuple.

```
fruits = ("apple", "orange","coconut" ,"banana", "coconut")
for x in fruits:
    print(x)
```

```
apple
orange
coconut
banana
coconut
```

## Summary.
Collections are single variables that are used to store multiple values.

List are ordered and changeable, and can be duplicate, the are created using [];

Sets are unordered and immutable, but we can add or remove from a set, and they do not accept duplicates. Created using {}.

Tuples are ordered and unchangeable, it allows duplicate values and the are much faster. Created using ().

Ok that’s is all about this article, i will be coming up with another article on how to understand dictionaries in python. Please do well to ask your questions in the comment section. Adios