Python lists, dicts, and functions for Javascript Engineers
Tags: python, javascript
Published: 2020-04-01 03:06:43

I’ve been getting really into Python recently. There’s been times in the past where I’ve dabbled or built things in Python but something about this recent “build a microservice” project at work has inspired me to learn more and increase my expertise. That project has since left my team’s hands due to sudden company restructuring but I feel happy to pursue the world of Python in my own time for now. Here’s even more things I’ve learned.

For the curious, here’s my previous post: [7 Python basics for JavaScript Engineers](https://stuartdotson.com/blog/7-python-basics-for-javascript-engineers/).

### Merging Arrays/Lists

In Javascript:

    // spread two arrays
    [...array1, ...array2]
    
    // concat one array onto another
    // does not mutate array1
    array1.concat(array2)

In Python:

    // mutates original list
    list1.extend(list2)
    
    // equivalent of spread operator for Python lists
    combined_list = [*list1, *list2]

### Merging Objects

In Javascript:

    // merge multiple objects together
    Object.assign({}, object1, object2);
    
    // spread operator for objects is still ... in JavaScript
    const mergedObject = { ...object1, ...object2 };

In Python:

    // Python uses ** to spread dicts
    merged_dict = { **dict1, **dict2 }

### Shallow copying gotchas

In the above solutions, only shallow copies are created. If you modify deeply nested  values on one, the other will change as well! That’s because objects and arrays more than a level deep are copied by reference and refer to the same place in memory. JavaScript and Python are very similar in this way.

For example in Python:

    a = [{ "foo": { "bar": "foobar" }}]
    b = [*a]
    b[0]["foo"]["bar"] = "foo whoa”
    print(a)// [{'foo': {'bar': 'foo whoa'}}]a[0] is b[0]
    // True

I talked about this already in-depth in the [JavaScript magic show post](https://stuartdotson.com/blog/javascript-magic-show/), but here’s a quick example:

    const a = [{ foo: { bar: 'foobar' }}];
    const b = [...a];
    b[0].foo.bar = 'foo whoa';
    console.log(a);
    // [{foo: { bar: 'foo whoa'}}]
    Object.is(a[0], b[0]);
    // true

Most of the time this doesn’t matter, but if you need real deep copies of nested objects and arrays, you need something like [copy.deepcopy](https://docs.python.org/2/library/copy.html) in Python or [immutability-helper](//github.com/kolodny/immutability-helper) for JavaScript.

### Keyword and positional function arguments

In Python, you can give folks the option of using keywords for your function arguments or just the standard order position you may be more familiar with. I’ll give an example of each.

    def my_func(arg1, arg2, arg3):
      return arg1, arg2, arg3
    
    // called with keywords
    my_func(arg1="arg1 value", arg2="arg2 value", arg3="arg3 value")
    
    // called positionally
    my_func("arg1 value", "arg2 value", "arg3 value")

You can even mix the different argument styles with the caveat that you cannot do a positional argument after a keyword argument.

This is ok:

    my_func("arg1 value", arg2="arg2 value", arg3="arg3 value")

This is not ok:

    my_func("arg1 value", arg2="arg2 value", "arg3 value")

In Javascript, every function argument is positional. You can get close to keyword arguments by having a object and destructuring like so:

    const myFunc = ({  arg1,  arg2,  etc}) => {
      return [arg1, arg2, etc];
    };

### Default function arguments

Default function arguments work the same in JavaScript and Python.

JavaScript:

    const myFunc = (
      arg1 = “arg1 default”,  
      arg2 = “arg2 default”
    ) {
      return [arg1, arg2];
    };

Python:

    def my_func(arg1="arg1 default value", arg2="arg2 default value"):
      return arg1, arg2

I hope this has been helpful for everybody and look forward to sharing more about my journey.