This is the 3rd part of 4-article series about analogies in Python and JavaScript. In the previous parts we covered a large part of the traditional Python 2.7 and JavaScript based on the ECMAScript 5 standard. This time we will start looking into Python 3.6 and JavaScript based on the ECMAScript 6 standard. ECMAScript 6 standard is pretty new and supported only the newest versions of browsers. For older browsers you will need Babel to compile your next-generation JavaScript code to the cross-browser-compatible equivalents. It opens the door to so many interesting things to explore. We will start from string interpolation, unpacking lists, lambda functions, iterations without indexes, generators, and sets!
Variables in strings
The old and inefficient way to build strings with values from variables is this concatenation:
name = 'World'
value = 'Hello, ' + name + '!\nWelcome!'
This can get very sparse and difficult to read. Also it is very easy to miss whitespaces in the sentence around variables.
Since Python version 3.6 and JavaScript based on the ECMAScript 6 standard, you can use so called string interpolation. These are string templates which are filled in with values from variables.
In Python they are also called f-string, because their notation starts with letter "f":
name = 'World'
value = f"""Hello, {name}!
Welcome!"""
price = 14.9
value = f'Price: {price:.2f} €' # 'Price: 14.90 €'
In JavaScript string templates start and end with backticks:
name = 'World';
value = `Hello, ${name}!
Welcome!`;
price = 14.9;
value = `Price ${price.toFixed(2)} €`; // 'Price: 14.90 €'
Note that string templates can be of a single line as well as of multiple lines. For f-strings in Python you can pass the format for variables, but you can't call methods of a variable unless they are properties and call getter methods.
Unpacking lists
Python and now JavaScript has an interesting feature to assign items of sequences into separate variables. For example, we can read the three values of a list into variables a, b, and c with the following syntax:
[a, b, c] = [1, 2, 3]
For tuples the parenthesis can be omitted. The following is a very popular way to swap values of two variables in Python:
a = 1
b = 2
a, b = b, a # swap values
With the next generation JavaScript this can also be achieved:
a = 1;
b = 2;
[a, b] = [b, a]; // swap values
In Python 3.6 if we have an unknown number of items in a list or tuple, we can assign them to a tuple of several values while also unpacking the rest to a list:
first, second, *the_rest = [1, 2, 3, 4]
# first == 1
# second == 2
# the_rest == [3, 4]
This can also be done with JavaScript (ECMAScript 6):
[first, second, ...the_rest] = [1, 2, 3, 4];
// first === 1
// last === 2
// the_rest === [3, 4]
Lambda functions
Python and JavaScript have a very neat functionality to create functions in a single line. These functions are called lambdas. Lambdas are very simple functions that take one or more arguments and return some calculated value. Usually lambdas are used when you need to pass a function to another function as a callback or as a function to manipulate every separate elements in a sequence.
In Python, you would define a lambda using the lambda
keyword, like this:
sum = lambda x, y: x + y
square = lambda x: x ** 2
In JavaScript lambdas use the =>
notation. If there are more than one arguments, they have to be in parenthesis:
sum = (x, y) => x + y;
square = x => Math.pow(x, 2);
Iteration without indexes
Many programming languages allow iterating through a sequence only by using indexes and incrementing their values. Then to get an item at some position, you would read it from an array, for example:
for (i=0; i<items.length; i++) {
console.log(items[i]);
}
This is not a nice syntax and is very technical - it doesn't read naturally. What we really want is just to grab each value from the list. And Python has a very neat possibility just to iterate through the elements:
for item in ['A', 'B', 'C']:
print(item)
In the modern JavaScript this is also possible with the for..of
operator:
for (let item of ['A', 'B', 'C']) {
console.log(item);
}
You can also iterate through a string characters in Python:
for character in 'ABC':
print(character)
And in the modern JavaScript:
for (let character of 'ABC') {
console.log(character);
}
Generators
Python and modern JavaScript has a possibility to define special functions through which you can iterate. With each iteration they return the next generated value in a sequence. These functions are called generators. With generators you can get numbers in a range, lines from a file, data from different paginated API calls, fibonacci numbers, and any other dynamicly generated sequences.
Technically generators are like normal functions, but instead of returning a value, they yield a value. This value will be returned for one iteration. And this generation happens as long as the end of the function is reached.
To illustrate that, the following Python code will create a generator countdown()
which will return numbers from the given one back to 1, (like 10, 9, 8, ..., 1):
def countdown(counter):
while counter > 0:
yield counter
counter -= 1
for counter in countdown(10):
print(counter)
Exactly the same can be achieved in modern JavaScript, but notice the asterisk at the function
statement. It defines that it's a generator:
function* countdown(counter) {
while (counter > 0) {
yield counter;
counter--;
}
}
for (let counter of countdown(10)) {
console.log(counter);
}
Sets
We already had a look at lists, tuples and arrays. But here is another type of data - sets. Sets are groups of elements that ensure that each element there exists only once. Set theory also specifies set operations like union, intersection, and difference, but we won't cover them here today.
This is how to create a set, add elements to it, check if a value exists, check the total amount of elements in a set, and iterate through its values, and remove a value using Python:
s = set(['A'])
s.add('B'); s.add('C')
'A' in s
len(s) == 3
for elem in s:
print(elem)
s.remove('C')
Here is how to achieve the same in modern JavaScript:
s = new Set(['A']);
s.add('B').add('C');
s.has('A') === true;
s.size === 3;
for (let elem of s.values()) {
console.log(elem);
}
s.delete('C')
The Takeaways
- String interpolation or literal templates allows you to have much cleaner and nicer code even with a possibility to have multiple lines of text.
- You can iterate through elements in a sequence or group without using indexes.
- Use generators when you have a sequence of nearly unlimited elements.
- Use sets when you want to ensure fast check if data exists in a collection.
- Use lambdas when you need short and clear single-line functions.
As you know from the previous parts, I am offering a cheat sheet with the whole list of equivalents in Python and JavaScript, both, time honored and future proof. To have something printed in front of your eyes is much more convenient than switching among windows or scrolling up and down until you find what you exactly were searching for. So I suggest you to get the cheat sheet and use it for good!
Get the Ultimate Cheat Sheet of
Equivalents in Python and JavaScript
✨✨✨
In the next and last part of the series, we will have a look at function arguments, classes, inheritance, and properties. Stay tuned!
Cover photo by Alex Knight
Top comments (5)
You can find all 4 parts of the series here: Part 1, Part 2, Part 3, Part 4
Also feel free to buy the cheat sheet which will surely save you time when looking for the correct methods or syntax in your lesser known language.
You’re creating a false equivalency between arrow functions and lambda functions. Just because they look syntactically similar doesn’t mean that they have the same behavior.
Lambda functions are Python’s anonymous functions.
Arrow functions are not JavaScript’s anonymous functions, because any type of function can be anonymous.
Both lambda functions and JS functions can be bound to a reference (although you should never do this in Python)
I think the key point here is that functions are first order objects in JavaScript and Python. That’s how they’re similar.
I would say that they might be implemented differently architecturally, but the behaviors of my given examples are equivalent.
Really enjoyed this article. Shared it with my team.
Thanks. I am glad you liked it :) The last part will also be interesting.