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 | from types import NoneType # for tensor
from copy import deepcopy # for tensor
def tensor(sizes=0, elem=0):
"""tensor(sizes=0, elem=0): creates a list of lists of lists...
The parameter sizes can be a number or a tuple/list or sizes.
>>> tensor()
[]
>>> tensor(())
[]
It works with a single number or a sequence of numbers:
>>> tensor(3)
[0, 0, 0]
>>> tensor((3))
[0, 0, 0]
>>> tensor((3), None)
[None, None, None]
>>> tensor((2, 3)) # array of 2 rows and 3 colums.
[[0, 0, 0], [0, 0, 0]]
>>> tensor((2, 3), 2)
[[2, 2, 2], [2, 2, 2]]
>>> tensor((1, 2, 3))
[[[0, 0, 0], [0, 0, 0]]]
>>> tensor((2, 2, 3))
[[[0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0]]]
It works with mutables too, calling deepcopy:
>>> r = tensor((2, 3), [3])
>>> r
[[[3], [3], [3]], [[3], [3], [3]]]
>>> r[0][2][0] = 0
>>> r
[[[3], [3], [0]], [[3], [3], [3]]]
"""
if isinstance(sizes, (int, long)):
sizes = [sizes]
elif not isinstance(sizes, list):
sizes = list(sizes)
result = []
if sizes:
first = sizes.pop()
if isinstance(elem, (int, long, basestring, tuple, NoneType, bool)):
result = [elem] * first
else:
result = [deepcopy(elem) for i in xrange(first)]
while sizes:
result = [deepcopy(result) for i in xrange(sizes.pop())]
return result
def transpose(m):
"""transpose(m): transposes a 2D matrix, made of tuples or lists of tuples or lists,
keeping their type.
>>> transpose([])
Traceback (most recent call last):
...
IndexError: list index out of range
>>> transpose([[]])
[]
>>> transpose([1,2,3])
Traceback (most recent call last):
...
TypeError: zip argument #1 must support iteration
>>> transpose([[1,2,3]])
[[1], [2], [3]]
>>> transpose( [[2, 2, 2], [2, 2, 2]] )
[[2, 2], [2, 2], [2, 2]]
>>> transpose( [(2, 2, 2), (2, 2, 2)] )
[(2, 2), (2, 2), (2, 2)]
>>> transpose( ([2, 2, 2], [2, 2, 2]) )
([2, 2], [2, 2], [2, 2])
>>> transpose( ((2, 2, 2), (2, 2, 2)) )
((2, 2), (2, 2), (2, 2))
>>> t = [[[1], [2]], [[3], [4]], [[5], [6]]]
>>> transpose(t)
[[[1], [3], [5]], [[2], [4], [6]]]
"""
if isinstance(m, list):
if isinstance(m[0], list):
return map(list, zip(*m))
else:
return zip(*m) # faster
else:
if isinstance(m[0], list):
return tuple(map(list, zip(*m)))
else:
return tuple( zip(*m) )
if __name__ == "__main__":
import doctest
doctest.testmod()
print "Tests done."
|
Comments
Deepcopy. I really don't like deepcopying values using the deepcopy() function. It slows your algorithm down and is kind of a last resort. Although the simplicity of the algorithm may be destroyed I would suggest more case analysis. For instance if L is a list of immutables it is appropriate to clone it using K = L[:]. One might even think about using a lazy datatype, that creates columns on demand ( depends on usage of course ).
Sign in to comment