Skip to content

Commit 89d5d6c

Browse files
authored
Merge pull request #287 from realpython/python-inherit-list-userlist
Create sample code for `UserList` vs `list`
2 parents 26a9ae5 + c9a6d92 commit 89d5d6c

File tree

8 files changed

+195
-0
lines changed

8 files changed

+195
-0
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Custom Python Lists: Inheriting From list vs UserList
2+
3+
This folder provides the code examples for the article [Custom Python Lists: Inheriting From list vs UserList
4+
](https://realpython.com/inherit-python-list/).
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
class CustomList(list):
2+
def join(self, separator=" "):
3+
return separator.join(str(item) for item in self)
4+
5+
def map(self, action):
6+
return type(self)(action(item) for item in self)
7+
8+
def filter(self, predicate):
9+
return type(self)(item for item in self if predicate(item))
10+
11+
def for_each(self, func):
12+
for item in self:
13+
func(item)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from collections import UserList
2+
3+
4+
class CustomList(UserList):
5+
def join(self, separator=" "):
6+
return separator.join(str(item) for item in self)
7+
8+
def map(self, action):
9+
return type(self)(action(item) for item in self.data)
10+
11+
def filter(self, predicate):
12+
return type(self)(item for item in self if predicate(item))
13+
14+
def for_each(self, func):
15+
for item in self.data:
16+
func(item)
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
class NumberList(list):
2+
def __init__(self, iterable):
3+
super().__init__(self._validate_number(item) for item in iterable)
4+
5+
def __setitem__(self, index, item):
6+
super().__setitem__(index, self._validate_number(item))
7+
8+
def insert(self, index, item):
9+
super().insert(index, self._validate_number(item))
10+
11+
def append(self, item):
12+
super().append(self._validate_number(item))
13+
14+
def extend(self, other):
15+
if isinstance(other, type(self)):
16+
super().extend(other)
17+
else:
18+
super().extend(self._validate_number(item) for item in other)
19+
20+
def _validate_number(self, value):
21+
if isinstance(value, (int, float, complex)):
22+
return value
23+
raise TypeError(f"numeric value expected, got {type(value).__name__}")
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from collections import UserList
2+
3+
4+
class NumberList(UserList):
5+
def __init__(self, iterable):
6+
super().__init__(self._validate_number(item) for item in iterable)
7+
8+
def __setitem__(self, index, item):
9+
self.data[index] = self._validate_number(item)
10+
11+
def insert(self, index, item):
12+
self.data.insert(index, self._validate_number(item))
13+
14+
def append(self, item):
15+
self.data.append(self._validate_number(item))
16+
17+
def extend(self, other):
18+
if isinstance(other, type(self)):
19+
self.data.extend(other)
20+
else:
21+
self.data.extend(self._validate_number(item) for item in other)
22+
23+
def _validate_number(self, value):
24+
if isinstance(value, (int, float, complex)):
25+
return value
26+
raise TypeError(f"numeric value expected, got {type(value).__name__}")
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import timeit
2+
from collections import UserList
3+
4+
5+
class StringList_list(list):
6+
def __init__(self, iterable):
7+
super().__init__(str(item) for item in iterable)
8+
9+
def __setitem__(self, index, item):
10+
super().__setitem__(index, str(item))
11+
12+
def insert(self, index, item):
13+
super().insert(index, str(item))
14+
15+
def append(self, item):
16+
super().append(str(item))
17+
18+
def extend(self, other):
19+
if isinstance(other, type(self)):
20+
super().extend(other)
21+
else:
22+
super().extend(str(item) for item in other)
23+
24+
25+
class StringList_UserList(UserList):
26+
def __init__(self, iterable):
27+
super().__init__(str(item) for item in iterable)
28+
29+
def __setitem__(self, index, item):
30+
self.data[index] = str(item)
31+
32+
def insert(self, index, item):
33+
self.data.insert(index, str(item))
34+
35+
def append(self, item):
36+
self.data.append(str(item))
37+
38+
def extend(self, other):
39+
if isinstance(other, type(self)):
40+
self.data.extend(other)
41+
else:
42+
self.data.extend(str(item) for item in other)
43+
44+
45+
init_data = range(10000)
46+
47+
extended_list = StringList_list(init_data)
48+
list_extend = (
49+
min(
50+
timeit.repeat(
51+
stmt="extended_list.extend(init_data)",
52+
number=5,
53+
repeat=2,
54+
globals=globals(),
55+
)
56+
)
57+
* 1e6
58+
)
59+
60+
extended_user_list = StringList_UserList(init_data)
61+
user_list_extend = (
62+
min(
63+
timeit.repeat(
64+
stmt="extended_user_list.extend(init_data)",
65+
number=5,
66+
repeat=2,
67+
globals=globals(),
68+
)
69+
)
70+
* 1e6
71+
)
72+
73+
print(f"StringList_list().extend() time: {list_extend:.2f} μs")
74+
print(f"StringList_UserList().extend() time: {user_list_extend:.2f} μs")
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
class StringList(list):
2+
def __init__(self, iterable):
3+
super().__init__(str(item) for item in iterable)
4+
5+
def __setitem__(self, index, item):
6+
super().__setitem__(index, str(item))
7+
8+
def insert(self, index, item):
9+
super().insert(index, str(item))
10+
11+
def append(self, item):
12+
super().append(str(item))
13+
14+
def extend(self, other):
15+
if isinstance(other, type(self)):
16+
super().extend(other)
17+
else:
18+
super().extend(str(item) for item in other)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from collections import UserList
2+
3+
4+
class StringList(UserList):
5+
def __init__(self, iterable):
6+
super().__init__(str(item) for item in iterable)
7+
8+
def __setitem__(self, index, item):
9+
self.data[index] = str(item)
10+
11+
def insert(self, index, item):
12+
self.data.insert(index, str(item))
13+
14+
def append(self, item):
15+
self.data.append(str(item))
16+
17+
def extend(self, other):
18+
if isinstance(other, type(self)):
19+
self.data.extend(other)
20+
else:
21+
self.data.extend(str(item) for item in other)

0 commit comments

Comments
 (0)