I’ve been getting really into Python. 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.
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, 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 in Python or 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.