Site icon Karneliuk

From Python to Go 004. Arrays, Lists, Slices.

Hello my friend,

In this post we will start exploring how to store multiple values in a single variable. There are multiple approaches how this can be achieved both in Python and Go (Golang). The first one we’ll cover is using ordered something of elements. We’ve used word “something”, because in Python this is called list, whilst Go (Golang) use the term slice. Let’s see what is similar and what is not between Python and Go (Golang).

Who Else Deals With Network Automation?

Just this week there was a massive event Autocon2, which is the biggest gathering of network automation enthusiasts from the entire world. People from different industries shared their experience, success stories and challenges. Whilst many of those insights are different, all of them revolve around the central idea that network automation is a must.

We have started doing network automation trainings before it become mainstream, yet we constantly update its content with new things. Start your training today to onboard the training, which is just leaving the platform.:

We offer the following training programs in network automation for you:

During these trainings you will learn the following topics:

Moreover, we put all mentions technologies in the context of real use cases, which our team has solved and are solving in various projects in the service providers, enterprise and data centre networks and systems across the Europe and USA. That gives you opportunity to ask questions to understand the solutions in-depth and have discussions about your own projects. And on top of that, each technology is provided with online demos and labs to master your skills thoroughly. Such a mixture creates a unique learning environment, which all students value so much. Join us and unleash your potential.

Start your automation training today.

What Are We Going To Talk Today About?

In order for you to be able to write any meaningful application, it is critical to be able to handle multiple values within a single variable. To give you some ideas from network and IT infrastructure automation:

And this list continues going on and on. Right, I have used word “list”, which is actually a term used for sequence of items in Python. So what we are going to discuss today is provided in another list:

  1. What are the the lists, arrays, slices in Python and Go (Golang)?
  2. How to create and to use them?
  3. What the most popular functions to deal with lists/slices and how to use them?

Explanation

In general, irrespective to programming languages, list is a sequence of elements. Even in this blog post I’ve already used a numbered list, where elements are prepended with a digit (1, 2, 3,..), and an unnumbered list, where elements starts with dash “-“. When we talk about programming languages though, the terminology matters. Let’s review it:

As a key take a way:

In Go (Golang) both slices and arrays are statically typed, meaning that all the elements must be of the same data type. It is possible though to break this using interfaces, which we will cover later in this series, but it is rather not recommended unless you have very strong reason to do so, which you typically don’t

The most common operations you use with the respect to list/slices, which are not applicable for arrays as they change the length:

  1. Adding new elements.
  2. Deleting elements.

The most common operations, which are applicable to lists/slices AND arrays, as they don’t change the length:

  1. Change the value of the existing element.
  2. Sorting elements using some order.
  3. Reversing elements’ order.
  4. Looking up if certain element exists.

It is good enough from the theory perspective, as all the things we are practically oriented, so let’s see how all that works.

Examples

The scenario, which you will see now both in Python and Go (Golang), relies on the previous blog post, where we introduced how to read variables from environment in Linux or MAC. On top of that we build the following:

  1. All the input variables are passed as a single comma-separated string of variables
  2. Some function is used it to separate string into a list/slice
  3. Apply all the operations we’ve mentioned above to the list/slice.
  4. Convert the list/slice back into a sting.

Python

The Python code for this scenario is the following:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
"""From Python to Go: Python: 004 - lists and slices"""

# Import part
import os


# Functions
def get_automation_input() -> str:
    """Helper function to get the automation input"""
    return os.getenv("AUTOMATION_INPUT")


# Read environmental value
automation_input = get_automation_input()
print(f"{automation_input=}")

# Create a list from string
automation_list = automation_input.split(",")
print(f"{automation_list=}")

# Add an element to the end of the list
automation_list.append("new_device")
print(f"{automation_list=}")

# Add an element to the beginning of the list
automation_list.insert(0, "provisioning_required")

# Check if that element is in the list
if "provisioning_required" in automation_list:
    print(f"provisioning_required is for the device {automation_list[1]}")

# Remove an element from the list
automation_list.remove("new_device")
print(f"{automation_list=}")

# Change the element in the list
automation_list[0] = "provisioning_done"
print(f"{automation_list=}")

# Remove the element by index
del automation_list[0]
print(f"{automation_list=}")

# Sort the list
automation_list.sort()
print(f"{automation_list=}")

# Reverse the list
automation_list.reverse()
print(f"{automation_list=}")

# Merger list into a string
automation_string = ",".join(automation_list)
print(f"{automation_string=}")

Each step is commented, so you can see how you can add/modify/delete elements in list Python as well as to do the lookup, sorting and reversing the order. Still, we’ll comment some key things:

Method is a function applied to an object and is part of class. We’ll cover object-oriented programming later in this series. Python is OOP-first language, which means that majority of things there are objects.

It is worth mentioning, that as methods are applied to objects, in many cases they change the values inside those objects; as such, you don’t need to store the results of methods’ executions. Therefore, all methods applied to the list object changed it internals. It is not always they case though, as method split generated brand new object as the result of its execution. So always refer to documentation.

Here’s an example of the Python script execution:


1
2
3
4
5
6
7
8
9
10
11
12
13
$ export AUTOMATION_INPUT="lab-switch001,ssh,karneliuk,lab"

$ python3 main.py
automation_input='lab-switch001,ssh,karneliuk,lab'
automation_list=['lab-switch001', 'ssh', 'karneliuk', 'lab']
automation_list=['lab-switch001', 'ssh', 'karneliuk', 'lab', 'new_device']
provisioning_required is for the device lab-switch001
automation_list=['provisioning_required', 'lab-switch001', 'ssh', 'karneliuk', 'lab']
automation_list=['provisioning_done', 'lab-switch001', 'ssh', 'karneliuk', 'lab']
automation_list=['lab-switch001', 'ssh', 'karneliuk', 'lab']
automation_list=['karneliuk', 'lab', 'lab-switch001', 'ssh']
automation_list=['ssh', 'lab-switch001', 'lab', 'karneliuk']
automation_string='ssh,lab-switch001,lab,karneliuk'

Try to replicate the example and experiment further.

Go (Golang)

Let’s now implement the very same scenario in Go (Golang):


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/* From Python to Go: Python: 004 - lists */

package main

// Import
import (
    "fmt"
    "os"
    "slices"
    "strings"
)

// Aux functions
func getAutomationInput() string {
    /* Helper function to get the automation input */
    return os.Getenv("AUTOMATION_INPUT")
}

// Main functions
func main() {
    // Get the input
    automationInput := getAutomationInput()
    fmt.Println(automationInput)

    // Create a slice
    automationSlice := strings.Split(automationInput, ",")
    fmt.Println(automationSlice)

    // Add new element to the end of the slice
    automationSlice = append(automationSlice, "new_device")
    fmt.Println(automationSlice)

    // Add new element to the beginning of the slice
    automationSlice = slices.Insert(automationSlice, 0, "provisioning_required")
    fmt.Println(automationSlice)

    // Check if the element exist in the slice
    if slices.Contains(automationSlice, "provisioning_required") {
        fmt.Printf("provisioning_required is for the device %v\n", automationSlice[0])
    }

    // Remove elemement from the slice and by index
    deleteIndex := slices.Index(automationSlice, "new_device")
    automationSlice = append(automationSlice[:deleteIndex], automationSlice[deleteIndex+1:]...)
    fmt.Println(automationSlice)

    // Change element
    automationSlice[0] = "provisioning_done"
    fmt.Println(automationSlice)

    // Sort the slice
    slices.Sort(automationSlice)
    fmt.Println(automationSlice)

    // Reverse the slice
    slices.Reverse(automationSlice)
    fmt.Println(automationSlice)

    // Merge list into the slice
    automationString := strings.Join(automationSlice, ",")
    fmt.Println(automationString)
}

As with Python, we’ve added a lot of comments to the code for you to ease its understanding. And as with Python, we provide some further comments:

  1. One big difference is that you can see between Go / Golang and Python is that Go is not really object oriented. Where you would have methods in Python, in Go, in majority of cases, you see functions with multiple input arguments, with one of the arguments being the variable you want to modify. The vast majority of functions associated with slices are available in a standard package “slices“.
  2. Names of functions in many cases are the same as you have in Python methods, which make sense as those are English words describing an operation.
  3. In certain cases, you need to save the result of the function execution (e.g., append() function when you add element or elements to the slice, slices.Insert() to add element to a slice at any position, slices.Index() to find a position of an element). Function append() takes two argument: first is the slice, where you add elements to, and the second is an element (in case we add another slice, we need to unpack it to elements using “” operator).
  4. Some functions don’t require for you to store the result of their execution (e.g., slices.Reverse() or slices.Sort()) as they change the content of the array associated with the slice and therefore the changes are reflected in the original slice as well.
  5. The biggest difference between Python and Go/Golang is how to delete the element from slice. In Go you cannot delete element that simple as slice is associated with an array, which has a fixed length. So what you do in essence is that you create a new slice pointing to new array, which is created without the element you want to delete and then garbage collector in Go frees memory associated with the array.
  6. When you provide in square brackets not a single index, but two index separated by column, that refers to a sub-slice (or slice of list in Python). If you use column, but provides only a single index, depending where the column is with the respect to index, it either means that you query of the elements from the beginning of the list to your index (e.g., [:5]) or from the current index till the end of the list (e.g., [5:])

Let’s see the execution of the example:


1
2
3
4
5
6
7
8
9
10
11
$ go run .
lab-switch001,ssh,karneliuk,lab
[lab-switch001 ssh karneliuk lab]
[lab-switch001 ssh karneliuk lab new_device]
[provisioning_required lab-switch001 ssh karneliuk lab new_device]
provisioning_required is for the device provisioning_required
[provisioning_required lab-switch001 ssh karneliuk lab]
[provisioning_done lab-switch001 ssh karneliuk lab]
[karneliuk lab lab-switch001 provisioning_done ssh]
[ssh provisioning_done lab-switch001 lab karneliuk]
ssh,provisioning_done,lab-switch001,lab,karneliuk

Lessons in GitHub

You can find the final working versions of the files from this blog at out GitHub page.

Conclusion

Starting from this blog post, as we have promised in the previous one, you start seeing the difference between Python and Go/Golang beyond the simple syntax. They are different in the very nature: with Python being object-oriented programming language and Go being procedural-oriented programming language; you should think different when you develop applications with them. Take care and good bye.

Support us






P.S.

If you have further questions or you need help with your networks, I’m happy to assist you, just send me message. Also don’t forget to share the article on your social media, if you like it.

BR,

Anton Karneliuk 

Exit mobile version