Search code examples
pythonoperatorsslice

How exactly [:] operator works in tuples in Python?


When I was working with Colorgram Library, I came across a [:] operator that I didn't understand.

print(extraction[0]) prints [<colorgram.py Color: Rgb(r=245, g=243, b=238), 64.68350168350169%> Then extraction[0].rgb prints Rgb(r=245, g=243, b=238).

Here is the most confusing part:

When I enter print(extraction[0].rgb[:]), it prints (245, 243, 238). How exactly does the [:] operator work here?

import colorgram
 
extraction = colorgram.extract('img.jpg', 30)
colors = []
 
for c in extraction:
    colors.append(c.rgb[:])
 
print(colors)

Solution

  • According to the PyPi Colorgram Docs:

    colorgram.Color A color extracted from an image. Its properties are:

    Color.rgb - The color represented as a namedtuple of RGB from 0 to 255, e.g. (r=255, g=151, b=210).

    What is a Named Tuple?

    1. A named tuple is a subclass of a regular tuple provided by the collections module. It allows you to define a new tuple type with named fields (like attributes of an object) along with their corresponding indices.
    2. Named tuples are also immutable, just like regular tuples.
    3. Named tuples offer the advantage of more readable and self-documenting code since you can access fields by their names instead of integer indices.
    4. Named tuples have built-in methods for conversion to dictionary and string representation, which can be useful.

    In your example, the Color named tuple is defined like so:

    >>> from collections import namedtuple  
    >>> Color = namedtuple('Rgb', ['r', 'g', 'b'])
    >>> my_color = Color(245, 243, 238)
    

    If you try printing my_color:

    >>> my_color
    Rgb(r=245, g=243, b=238)
    >>> type(my_color)
    <class '__main__.Rgb'>
    

    Now, if you try printing mycolor[:], you will notice the type of the sliced named tuple is no longer of type Rgb, but rather a vanilla Python tuple.

    >>> print(my_color[:])
    (245, 243, 238)
    >>> type(my_color[:])
    <class 'tuple'>
    

    If colorgram provides you with a named tuple, you can of course use indexing like with any tuple, but you can also access the attributes by name. For example, if I would like to access the g parameter of the Rgb tuple I can do any of the following.

    >>> my_color[1]
    243
    >>> my_color.g
    243
    >>> getattr(my_color, 'g')