Supported Collections
dbzero offers persistent versions of Python's common built-in collections. These collections, including dbzero.dict, dbzero.list, and dbzero.tuple, are designed to behave almost identically to their standard Python counterparts, so you can work with them as if they were regular Python objects.
The key difference is that dbzero collections are automatically persisted to the storage and managed within transactions. When transaction is commited, all changes to your collections are saved.
Dictionary (dbzero.dict)
A dbzero.dict is a mutable, unordered mapping of unique, hashable keys to values, just like a standard Python dict. It's your go-to for storing and retrieving data using a key.
Creating a Dictionary
You can create a dbzero.dict in several familiar ways:
import dbzero as db0
# Create an empty dictionary
d1 = db0.dict()
# Create from an iterable of key-value pairs
d2 = db0.dict([('name', 'Alice'), ('age', 30)])
# Create using keyword arguments
d3 = db0.dict(name="Bob", age=25)
# Create from another dictionary
py_dict = {'city': 'New York'}
d4 = db0.dict(py_dict)
# Create using fromkeys
d5 = db0.dict().fromkeys(['a', 'b', 'c'], 0)
# d5 is {'a': 0, 'b': 0, 'c': 0}Common Operations
dbzero.dict supports all the standard dictionary operations.
my_dict = db0.dict(item_1=10, item_2=20)
# Get the number of items
len(my_dict) # Returns 2
# Access an item by key
print(my_dict['item_1']) # Prints 10
# Add or update an item
my_dict['item_3'] = 30
my_dict['item_1'] = 15
# Check for a key's existence
'item_2' in my_dict # Returns True
'item_99' in my_dict # Returns False
# Delete an item by key
del my_dict['item_2']
assert 'item_2' not in my_dict
# Iterate over keys
for key in my_dict:
print(key, my_dict[key])KeyError: Accessing a non-existent key with my_dict["key"] will raise a KeyError, just like a standard dictionary. Use the .get() method to avoid this.
Methods
dbzero.dict implements the full dict API, including:
clear(): Removes all items from the dictionary.copy(): Returns a shallow copy of the dictionary as a standard Pythondict.get(key[, default]): Returns the value forkeyif it's in the dictionary, otherwise returnsdefault. Ifdefaultisn't given, it defaults toNone.pop(key[, default]): Removes the specified key and returns the corresponding value. If the key is not found,defaultis returned if provided, otherwise aKeyErroris raised.setdefault(key[, default]): Ifkeyis in the dictionary, return its value. If not, insertkeywith a value ofdefaultand returndefault.defaultdefaults toNone.update([other]): Updates the dictionary with the key/value pairs fromother, overwriting existing keys.items(),keys(),values(): Return dynamic view objects that display the dictionary's entries. These views reflect any subsequent changes to the dictionary.
d = db0.dict({'a': 1, 'b': 2})
# Using .get()
print(d.get('a')) # Prints 1
print(d.get('c', 0)) # Prints 0
# Using .pop()
val = d.pop('b')
print(val) # Prints 2
# Using .update()
d.update({'c': 3, 'a': 10})
# d is now {'a': 10, 'c': 3}
# Iterating over a view
for key, value in d.items():
print(f"{key}: {value}")Keys and Values
- Keys: Keys must be hashable. This includes common types like strings, numbers, booleans,
None, and tuples containing only hashable types. You can even use types themselves as keys. Unhashable types like lists or other dictionaries cannot be used as keys. - Values: Values can be any Python object, including other
dbzerocollections. This allows you to build complex, nested data structures that are fully persisted.
Persistence and Garbage Collection: When a dbzero.dict is modified (e.g., using clear(), pop(), del), dbzero automatically manages the lifecycle of its contents. If a dbzero object stored as a key or value is removed, its reference count is decreased, and it may be automatically garbage-collected by dbzero during the next commit if no other objects refer to it.
List (dbzero.list)
A dbzero.list is a mutable, ordered sequence of items, mirroring the functionality of a standard Python list. It's perfect for when you need an ordered collection.
Creating a List
Creating a dbzero.list is straightforward.
import dbzero as db0
# Create an empty list
list_1 = db0.list()
# Create a list from an iterable (like another list or tuple)
list_2 = db0.list([1, "hello", 3.14])Common Operations
You can interact with a dbzero.list using the same syntax as a regular list.
my_list = db0.list(['a', 'b', 'c'])
# Get the number of items
len(my_list) # Returns 3
# Access an item by index (supports negative indexing)
print(my_list[0]) # Prints 'a'
print(my_list[-1]) # Prints 'c'
# Update an item by index
my_list[1] = 'x'
# my_list is now ['a', 'x', 'c']
# Slicing
# Note: Slicing a db0.list returns a new standard Python list (a copy)
sub_list = my_list[0:2]
print(sub_list) # Prints ['a', 'x']
# Concatenation and multiplication
new_list = my_list + [1, 2]
rep_list = my_list * 2
# Check for an item's existence
'x' in my_list # Returns True
# Iterate over items
for item in my_list:
print(item)Methods
dbzero.list provides the complete list API:
append(x): Adds an item to the end of the list.clear(): Removes all items from the list.copy(): Returns a shallow copy as a standard Pythonlist.count(x): Returns the number of timesxappears in the list.extend(iterable): Extends the list by appending all the items from the iterable.index(x): Returns the zero-based index of the first item whose value is equal tox.pop([i]): Removes the item at the given position and returns it. If no index is specified, it removes and returns the last item.remove(x): Removes the first item from the list whose value is equal tox.
Persistence and Garbage Collection: Like dictionaries, dbzero lists manage the lifecycle of their dbzero object contents. Removing a dbzero object from a list (via pop, remove, clear, or slice assignment) will decrement its reference count, potentially leading to its deletion from the storage on the next commit.
Tuple (dbzero.tuple)
A dbzero.tuple is an immutable, ordered sequence of items, analogous to Python's tuple. Once created, its contents cannot be changed.
Creating a Tuple
You create a dbzero.tuple by passing a single iterable argument.
import dbzero as db0
# Create a tuple from a list
tuple_1 = db0.tuple([1, "hello", 3.14])
# Create an empty tuple
empty_tuple = db0.tuple()
# Create from a generator
gen = (x * x for x in range(3))
tuple_2 = db0.tuple(gen) # Results in (0, 1, 4)
# It can be compared with a standard Python tuple
assert tuple_1 == (1, "hello", 3.14)The dbzero.tuple() constructor accepts exactly one argument, which must be an iterable. Providing no arguments creates an empty tuple, but providing more than one argument or a non-iterable argument will raise a TypeError.
Common Operations
As tuples are immutable, the set of operations is smaller than for lists, focusing on access and inspection.
my_tuple = db0.tuple(['a', 'b', 'c'])
# Get the number of items
len(my_tuple) # Returns 3
# Access an item by index
print(my_tuple[1]) # Prints 'b'
# Unpacking
x, y, z = my_tuple
print(y) # Prints 'b'
# Iterate over items
for item in my_tuple:
print(item)Methods
dbzero.tuple supports the two standard, non-mutating tuple methods:
count(x): Returns the number of timesxappears in the tuple.index(x): Returns the zero-based index in the tuple of the first item whose value isx.
Immutability and Persistence: Because dbzero.tuple objects are immutable, you cannot change them after creation. However, they are still transactional. If a dbzero object containing a dbzero tuple is deleted, the references to the tuple's elements are also removed, following the same garbage collection rules as lists and dictionaries.