Session Overview
Welcome, JavaScript developers! This guide will help you understand how Python data types compare to JavaScript data types. We'll explore the similarities, differences, and unique features of both languages to ease your transition to Python programming. By understanding these comparisons, you'll be able to apply your JavaScript knowledge while quickly adapting to Python's conventions.
Fundamental Differences
Before diving into specific data types, let's understand some fundamental differences between Python and JavaScript:
Type Systems
- JavaScript: Weakly typed and dynamically typed. Variables can change types implicitly during operations.
- Python: Strongly typed but still dynamically typed. Variables can change types, but Python doesn't perform implicit type conversions during operations.
// JavaScript
let x = "5";
let y = x * 2; // y = 10, implicit conversion from string to number
# Python
x = "5"
y = x * 2 # Results in "55", not 10 (string duplication)
y = int(x) * 2 # Now y = 10, explicit conversion needed
Variable Declaration
- JavaScript: Uses
var,let, orconstto declare variables. - Python: No declaration needed. Variables are created when you first assign a value.
// JavaScript
let name = "Alice";
const age = 30;
# Python
name = "Alice"
age = 30 # No declaration keywords needed
Truthy and Falsy Values
- JavaScript: Has many falsy values (0, "", false, null, undefined, NaN).
- Python: Has fewer falsy values (False, None, 0, 0.0, "", [], {}, set(), etc.).
// JavaScript
if (0) console.log("This won't print"); // 0 is falsy
if ("0") console.log("This will print"); // "0" is truthy
# Python
if 0: print("This won't print") # 0 is falsy
if "0": print("This will print") # "0" is truthy
Analogy: Type Systems as Communication Styles
Think of the difference between JavaScript and Python's type systems like different communication styles:
- JavaScript is like a flexible, accommodating friend who tries to understand what you mean even if you mix languages or use vague terms. They'll make educated guesses about your meaning.
- Python is like a precise friend who speaks clearly but expects you to be explicit. They won't guess what you mean if you mix languages - you need to translate properly.
Both friends are helpful, but they have different expectations about how you communicate with them.
Primitive Data Types
Numbers
| JavaScript | Python | Key Differences |
|---|---|---|
Number - represents both integers and floating-point numbers
BigInt - for arbitrarily large integers (newer)
|
int - integers with unlimited precision
float - 64-bit floating-point numbers
complex - complex numbers (a + bj)
|
• Python has separate int and float types
• Python int has unlimited precision (like BigInt)
• Python has built-in complex numbers
• No NaN or Infinity literals in Python (use float("nan"), float("inf"))
|
// JavaScript
let num = 42; // Number
let float = 3.14; // Number
let bigInt = 1234567890123456789012345678901234567890n; // BigInt
let notANumber = NaN; // NaN is a special Number value
let infinity = Infinity; // Also a special Number value
# Python
num = 42 # int
float_num = 3.14 # float
big_int = 1234567890123456789012345678901234567890 # Still an int, no special syntax
complex_num = 3 + 4j # complex
not_a_number = float("nan") # Need to use float() function
infinity = float("inf") # Need to use float() function
Strings
| JavaScript | Python | Key Differences |
|---|---|---|
String - sequence of characters
Can use single or double quotes Template literals with backticks |
str - immutable sequence of characters
Can use single, double, or triple quotes |
• Python strings are immutable (can't be changed after creation)
• Python has triple quotes for multiline strings ( """text""")
• Python uses f-strings for string interpolation ( f"Hello {name}")
• Python has no separate character type |
// JavaScript
let singleQuoted = 'Hello';
let doubleQuoted = "World";
let template = `Hello, ${name}!`; // Template literal
let multiline = `This is a
multiline string`;
# Python
single_quoted = 'Hello'
double_quoted = "World"
f_string = f"Hello, {name}!" # f-string (similar to template literals)
multiline = """This is a
multiline string""" # Triple quotes
Booleans and None/Null
| JavaScript | Python | Key Differences |
|---|---|---|
true and false (lowercase)
null - explicit absence of value
undefined - uninitialized variable
|
True and False (capitalized)
None - represents absence of value
|
• Python booleans are capitalized
• Python has None but no equivalent of undefined
• None, False, and 0 are different but all falsy
|
// JavaScript
let isActive = true;
let noValue = null;
let uninitialized; // undefined
// Type checking
typeof true; // "boolean"
typeof null; // "object" (a historical JavaScript bug)
typeof undefined; // "undefined"
# Python
is_active = True
no_value = None
# Type checking
type(True) #
type(None) #
Collection Data Types
Arrays vs Lists
| JavaScript Arrays | Python Lists | Key Differences |
|---|---|---|
|
Mutable, ordered collections
Can contain mixed types Methods: push, pop, shift, unshift, slice, splice, etc. |
Mutable, ordered collections
Can contain mixed types Methods: append, extend, insert, remove, pop, etc. |
• Python doesn't have push (use append)
• Python uses extend instead of concat
• Python's slice syntax is list[start:end]
• Python doesn't have splice - you use slicing assignment
|
// JavaScript
let arr = [1, 2, 3, "four", true];
arr.push(5); // Add to end: [1, 2, 3, "four", true, 5]
arr.pop(); // Remove from end: [1, 2, 3, "four", true]
arr.unshift(0); // Add to beginning: [0, 1, 2, 3, "four", true]
arr.shift(); // Remove from beginning: [1, 2, 3, "four", true]
let sliced = arr.slice(1, 3); // [2, 3]
arr.splice(1, 1, "two"); // Replace: [1, "two", 3, "four", true]
# Python
arr = [1, 2, 3, "four", True]
arr.append(5) # Add to end: [1, 2, 3, "four", True, 5]
arr.pop() # Remove from end: [1, 2, 3, "four", True]
arr.insert(0, 0) # Add to beginning: [0, 1, 2, 3, "four", True]
arr.pop(0) # Remove from beginning: [1, 2, 3, "four", True]
sliced = arr[1:3] # [2, 3]
arr[1:2] = ["two"] # Replace: [1, "two", 3, "four", True]
Objects vs Dictionaries
| JavaScript Objects | Python Dictionaries | Key Differences |
|---|---|---|
|
Key-value pairs (keys are strings or symbols)
Object literal syntax: {key: value}
Methods: Object.keys(), Object.values(), etc. |
Key-value pairs (keys can be any immutable type)
Dict literal syntax: {key: value}
Methods: keys(), values(), items(), etc. |
• Python dict keys can be any hashable type, not just strings
• Python dict methods are called on the object, not from a global object • Python has useful methods like get() with default value
• Python dict comprehensions: {k:v for k, v in ...}
|
// JavaScript
let person = {
name: "Alice",
age: 30,
"likes python": true
};
// Accessing properties
person.name; // "Alice"
person["likes python"]; // true
// Methods
Object.keys(person); // ["name", "age", "likes python"]
Object.values(person); // ["Alice", 30, true]
// Checking if a key exists
"name" in person; // true
# Python
person = {
"name": "Alice",
"age": 30,
"likes python": True
}
# Accessing properties
person["name"] # "Alice"
person["likes python"] # True
# person.name # Error! No dot notation for arbitrary keys
# Methods
person.keys() # dict_keys(["name", "age", "likes python"])
person.values() # dict_values(["Alice", 30, True])
person.items() # dict_items([("name", "Alice"), ("age", 30), ("likes python", True)])
# Getting with default (no KeyError)
person.get("height", 165) # 165 (default value if key doesn't exist)
# Checking if a key exists
"name" in person # True
Analogy: Dictionaries vs Objects
Think of JavaScript objects and Python dictionaries as different types of organizers:
- JavaScript objects are like filing cabinets where all the labels must be text or symbols. You can access files by opening a specific drawer (dot notation) or by using their label (bracket notation).
- Python dictionaries are like advanced filing systems where labels can be almost anything (numbers, tuples, strings, etc.) as long as they don't change. You have to use the label lookup system (brackets) to find files, but it comes with many built-in organization helpers (methods).
JavaScript Sets vs Python Sets
| JavaScript Sets | Python Sets | Key Differences |
|---|---|---|
|
Collection of unique values
Methods: add, delete, has, etc. Limited mathematical set operations |
Collection of unique, hashable objects
Methods: add, remove, discard, etc. Rich set of mathematical operations |
• Python sets can only contain hashable objects
• Python has robust mathematical set operations (union, intersection, etc.) • Python has set comprehensions: {x for x in ...}
• Python has immutable frozenset type |
// JavaScript
let set = new Set([1, 2, 3, 3]); // Set(3) {1, 2, 3}
set.add(4); // Set(4) {1, 2, 3, 4}
set.has(2); // true
set.delete(3); // Set(3) {1, 2, 4}
// Set operations (ES6+)
let set1 = new Set([1, 2, 3]);
let set2 = new Set([3, 4, 5]);
let union = new Set([...set1, ...set2]); // Set(5) {1, 2, 3, 4, 5}
# Python
set_a = {1, 2, 3, 3} # {1, 2, 3}
set_a.add(4) # {1, 2, 3, 4}
2 in set_a # True
set_a.remove(3) # {1, 2, 4}
# Set operations
set1 = {1, 2, 3}
set2 = {3, 4, 5}
union = set1 | set2 # {1, 2, 3, 4, 5}
intersection = set1 & set2 # {3}
difference = set1 - set2 # {1, 2}
symmetric_diff = set1 ^ set2 # {1, 2, 4, 5}
Maps vs Python Dictionaries
// JavaScript Map
let map = new Map();
map.set("key1", "value1");
map.set(42, "value2"); // Keys can be any type
map.get("key1"); // "value1"
map.has(42); // true
map.delete("key1"); // true
# Python Dictionary (Equivalent to JavaScript Map)
dict_a = {}
dict_a["key1"] = "value1"
dict_a[42] = "value2" # Keys can be any hashable type
dict_a["key1"] # "value1"
42 in dict_a # True
del dict_a["key1"] # Removes the key
Other Collection Types in Python
Python has several collection types that don't have direct JavaScript equivalents:
# Tuple - immutable sequence
coordinates = (10, 20) # Can't be modified after creation
first_coord = coordinates[0] # Access like lists
# Named Tuple - immutable with named fields
from collections import namedtuple
Person = namedtuple('Person', ['name', 'age'])
alice = Person('Alice', 30)
alice.name # 'Alice' - access by name
alice[0] # 'Alice' - access by index
# Deque - efficient append/pop at both ends
from collections import deque
queue = deque([1, 2, 3])
queue.append(4) # Add to right: [1, 2, 3, 4]
queue.appendleft(0) # Add to left: [0, 1, 2, 3, 4]
# Counter - count occurrences
from collections import Counter
c = Counter("hello") # Counter({'l': 2, 'h': 1, 'e': 1, 'o': 1})
Functions and Classes
Functions
| JavaScript Functions | Python Functions | Key Differences |
|---|---|---|
|
Function declarations or expressions
Arrow functions for concise syntax Functions are objects with properties |
Functions defined with def keyword
Lambda expressions for simple functions Functions are first-class objects |
• Python uses def instead of function
• Python's lambda is more limited than arrow functions
• Python supports advanced parameter features like default values, keyword arguments, and unpacking • Python functions can have docstrings |
// JavaScript Function
function add(a, b) {
return a + b;
}
// Arrow function
const multiply = (a, b) => a * b;
// Default parameters
function greet(name = "friend") {
return `Hello, ${name}!`;
}
// Rest parameters
function sum(...numbers) {
return numbers.reduce((total, num) => total + num, 0);
}
# Python Function
def add(a, b):
return a + b
# Lambda expression (similar to arrow function)
multiply = lambda a, b: a * b
# Default parameters
def greet(name="friend"):
return f"Hello, {name}!"
# Variable arguments (*args and **kwargs)
def sum(*numbers):
return sum(numbers)
def person_info(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
Classes and Objects
| JavaScript Classes | Python Classes | Key Differences |
|---|---|---|
|
ES6 class syntax
Prototype-based inheritance Constructor method |
Class definition with class keyword
Class-based inheritance __init__ method as constructor
|
• Python requires explicit self parameter for methods
• Python uses __init__ instead of constructor
• Python has special "dunder" methods ( __str__, __repr__, etc.)
• Python supports multiple inheritance |
// JavaScript Class
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
return `Hello, my name is ${this.name}`;
}
// Static method
static create(name, age) {
return new Person(name, age);
}
}
// Inheritance
class Employee extends Person {
constructor(name, age, title) {
super(name, age);
this.title = title;
}
work() {
return `${this.name} is working as a ${this.title}`;
}
}
// Usage
const alice = new Person("Alice", 30);
console.log(alice.greet());
# Python Class
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def greet(self):
return f"Hello, my name is {self.name}"
# Static method
@staticmethod
def create(name, age):
return Person(name, age)
# Inheritance
class Employee(Person):
def __init__(self, name, age, title):
super().__init__(name, age)
self.title = title
def work(self):
return f"{self.name} is working as a {self.title}"
# Usage
alice = Person("Alice", 30)
print(alice.greet())
Type Conversion and Checking
Type Conversion
| JavaScript | Python |
|---|---|
Number(value) or +value
String(value) or value.toString()
Boolean(value) or !!value
Array.from(value)
Object.entries(obj), Object.fromEntries(entries)
|
int(value), float(value)
str(value)
bool(value)
list(value), tuple(value)
dict(items)
|
// JavaScript
let num = Number("42"); // 42
let str = String(42); // "42"
let bool = Boolean(1); // true
let arr = Array.from("abc"); // ["a", "b", "c"]
let obj = Object.fromEntries([["a", 1], ["b", 2]]); // {a: 1, b: 2}
# Python
num = int("42") # 42
str_val = str(42) # "42"
bool_val = bool(1) # True
arr = list("abc") # ["a", "b", "c"]
dict_val = dict([("a", 1), ("b", 2)]) # {"a": 1, "b": 2}
Type Checking
| JavaScript | Python |
|---|---|
typeof value - primitive types
value instanceof Constructor - objects
Array.isArray(value) - special case for arrays
|
type(value) - returns the class/type
isinstance(value, Class) - check inheritance
issubclass(Class, ParentClass) - check class inheritance
|
// JavaScript
typeof 42; // "number"
typeof "hello"; // "string"
typeof true; // "boolean"
typeof undefined; // "undefined"
typeof {}; // "object"
typeof []; // "object" (can't distinguish arrays)
typeof null; // "object" (a JS quirk)
Array.isArray([]); // true
value instanceof Array; // true for arrays
value instanceof Object; // true for any object
# Python
type(42) #
type("hello") #
type(True) #
type(None) #
type({}) #
type([]) #
isinstance([], list) # True
isinstance([], object) # True for any object
issubclass(bool, int) # True (booleans are a subclass of integers in Python)
Common Pitfalls and Gotchas
Equality Comparisons
// JavaScript has == (loose equality) and === (strict equality)
1 == "1"; // true (loose equality with type coercion)
1 === "1"; // false (strict equality, no type coercion)
// Object equality checks reference, not contents
{} == {}; // false
{} === {}; // false
let obj = {};
obj == obj; // true
# Python has only == (value equality) and is (identity)
1 == "1" # False (no type coercion)
1 == 1.0 # True (value equality)
# Object equality checks value, not reference
{} == {} # True
{} is {} # False (different objects)
obj = {}
obj is obj # True
Mutable Default Arguments
// JavaScript - no issue with mutable defaults
function addItem(item, list = []) {
list.push(item);
return list;
}
addItem("a"); // ["a"]
addItem("b"); // ["b"] (new default list each time)
# Python - beware of mutable defaults!
def add_item(item, list=[]): # DANGER! list created only once
list.append(item)
return list
add_item("a") # ["a"]
add_item("b") # ["a", "b"] (same list reused!)
# Correct pattern:
def add_item_safe(item, list=None):
if list is None:
list = []
list.append(item)
return list
Variable Scoping
// JavaScript - block scope with let/const
function jsScope() {
if (true) {
let x = 10; // Block scoped
var y = 20; // Function scoped
}
console.log(y); // 20
console.log(x); // ReferenceError: x is not defined
}
# Python - function scope only
def python_scope():
if True:
x = 10 # Function scoped
y = 20 # Function scoped
print(x) # 10 - still in scope
print(y) # 20 - still in scope
Copying Objects
// JavaScript - shallow copy
let original = {a: 1, b: {c: 2}};
let shallowCopy = {...original}; // ES6 spread syntax
let deepCopy = JSON.parse(JSON.stringify(original)); // Simple deep copy
# Python - shallow copy
original = {'a': 1, 'b': {'c': 2}}
shallow_copy = original.copy() # or dict(original)
# Python - deep copy
import copy
deep_copy = copy.deepcopy(original)
Practical Examples
Data Processing
// JavaScript
const data = [
{ name: "Alice", age: 30, active: true },
{ name: "Bob", age: 25, active: false },
{ name: "Charlie", age: 35, active: true }
];
// Get active users
const activeUsers = data.filter(user => user.active);
// Map user names to uppercase
const upperNames = data.map(user => user.name.toUpperCase());
// Calculate average age
const averageAge = data.reduce((sum, user) => sum + user.age, 0) / data.length;
# Python
data = [
{"name": "Alice", "age": 30, "active": True},
{"name": "Bob", "age": 25, "active": False},
{"name": "Charlie", "age": 35, "active": True}
]
# Get active users
active_users = [user for user in data if user["active"]]
# Map user names to uppercase
upper_names = [user["name"].upper() for user in data]
# Calculate average age
average_age = sum(user["age"] for user in data) / len(data)
Asynchronous Code
// JavaScript - Promises and async/await
function fetchData() {
return fetch('https://api.example.com/data')
.then(response => response.json());
}
// With async/await
async function getData() {
try {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
return data;
} catch (error) {
console.error('Error:', error);
}
}
# Python - asyncio and async/await
import asyncio
import aiohttp
async def fetch_data():
async with aiohttp.ClientSession() as session:
async with session.get('https://api.example.com/data') as response:
return await response.json()
# With async/await
async def get_data():
try:
data = await fetch_data()
return data
except Exception as e:
print(f"Error: {e}")
# Running async code
asyncio.run(get_data())
Practice Exercises
Exercise 1: Type Conversion
Write functions in both JavaScript and Python to:
- Convert a list of mixed values to their corresponding string representations
- Filter out all falsy values from a collection
- Calculate the sum of all numeric values in a mixed-type collection
Exercise 2: Data Transformation
Given a list of objects/dictionaries representing people:
- Filter to find all people over 30
- Transform the data to a format grouping people by age ranges
- Sort the list by name in alphabetical order
Exercise 3: Class Conversion
Take a JavaScript class you've written before and convert it to a Python class, ensuring it follows Python conventions and best practices.
Best Practices for JavaScript Developers Learning Python
- Embrace Pythonic Style: Follow PEP 8 style guidelines (snake_case for variables/functions, PascalCase for classes)
- Use List/Dict Comprehensions: Learn to use comprehensions instead of
map/filterwhen appropriate - Leverage Built-in Functions: Python has many useful built-in functions (
len,max,min,sum, etc.) - Avoid Overusing Classes: Python functions and modules can do a lot without needing classes
- Remember
selfParameter: Always includeselfas the first parameter in instance methods - Type Annotations: Consider using type hints (Python 3.5+) for better code clarity, especially if coming from TypeScript
- Context Managers: Use
withstatements for resource management instead of try/finally - Explicit is Better than Implicit: Python values clarity over terseness
# Good Pythonic code example
def process_user_data(users, min_age=18):
"""Process user data to get active users above a minimum age."""
active_adults = [
user for user in users
if user["active"] and user["age"] >= min_age
]
# Group by age decade
by_decade = {}
for user in active_adults:
decade = user["age"] // 10 * 10
if decade not in by_decade:
by_decade[decade] = []
by_decade[decade].append(user)
return {
"active_adult_count": len(active_adults),
"by_decade": by_decade,
"average_age": sum(user["age"] for user in active_adults) / len(active_adults) if active_adults else 0
}
Next Steps for JavaScript Developers
Now that you understand the key differences between Python and JavaScript data types, here are some next steps to deepen your Python knowledge:
- Explore the Standard Library: Python's built-in modules like
collections,itertools, andfunctoolsoffer powerful tools - Learn Generators and Iterators: These Python features can replace many array operations in JavaScript
- Dive into Decorators: Python's decorator pattern is powerful and widely used
- Understand Python's Context Managers: The
withstatement provides elegant resource management - Try Type Annotations: If you're used to TypeScript, exploring Python's typing module can help
- Learn Dependency Management: Understand pip, virtual environments, and requirements.txt
Additional Resources
- The Python Tutorial
- Real Python - Intermediate Tutorials
- PEP 8 - Style Guide for Python Code
- Pylint - A Python Linter
- Python Type Hints
In our next session, we'll explore control flow in Python, including conditionals, loops, and exception handling, and how they compare to JavaScript's control flow mechanisms.