forked from AllenDowney/ThinkPython2
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstructshape.py
More file actions
125 lines (90 loc) · 2.64 KB
/
structshape.py
File metadata and controls
125 lines (90 loc) · 2.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
"""This module contains a code example related to
Think Python, 2nd Edition
by Allen Downey
http://thinkpython2.com
Copyright 2015 Allen Downey
License: http://creativecommons.org/licenses/by/4.0/
"""
from __future__ import print_function, division
"""
This module provides one function, structshape(), which takes
an object of any type and returns a string that summarizes the
"shape" of the data structure; that is, the type, size and
composition.
"""
def structshape(ds):
"""Returns a string that describes the shape of a data structure.
ds: any Python object
Returns: string
"""
typename = type(ds).__name__
# handle sequences
sequence = (list, tuple, set, type(iter('')))
if isinstance(ds, sequence):
t = [structshape(x) for x in ds]
rep = f'{typename} of {listrep(t)}'
return rep
elif isinstance(ds, dict):
keys = set()
vals = set()
for k, v in ds.items():
keys.add(structshape(k))
vals.add(structshape(v))
rep = '%s of %d %s->%s' % (typename, len(ds),
setrep(keys), setrep(vals))
return rep
else:
return ds.__class__.__name__ if hasattr(ds, '__class__') else typename
def listrep(t):
"""Returns a string representation of a list of type strings.
t: list of strings
Returns: string
"""
current = t[0]
count = 0
res = []
for x in t:
if x == current:
count += 1
else:
append(res, current, count)
current = x
count = 1
append(res, current, count)
return setrep(res)
def setrep(s):
"""Returns a string representation of a set of type strings.
s: set of strings
Returns: string
"""
rep = ', '.join(s)
return rep if len(s) == 1 else f'({rep})'
def append(res, typestr, count):
"""Adds a new element to a list of type strings.
Modifies res.
res: list of type strings
typestr: the new type string
count: how many of the new type there are
Returns: None
"""
rep = typestr if count == 1 else '%d %s' % (count, typestr)
res.append(rep)
if __name__ == '__main__':
t = [1, 2, 3]
print(structshape(t))
t2 = [[1, 2], [3, 4], [5, 6]]
print(structshape(t2))
t3 = [1, 2, 3, 4.0, '5', '6', [7], [8], 9]
print(structshape(t3))
class Point:
"""trivial object type"""
t4 = [Point(), Point()]
print(structshape(t4))
s = set('abc')
print(structshape(s))
lt = zip(t, s)
print(structshape(lt))
d = dict(lt)
print(structshape(d))
it = iter('abc')
print(structshape(it))