def reshape(seq, how):
"""Reshape the sequence according to the template in ``how``.
Examples
========
>>> from sympy.utilities import reshape
>>> seq = range(1, 9)
>>> reshape(seq, [4]) # lists of 4
[[1, 2, 3, 4], [5, 6, 7, 8]]
>>> reshape(seq, (4,)) # tuples of 4
[(1, 2, 3, 4), (5, 6, 7, 8)]
>>> reshape(seq, (2, 2)) # tuples of 4
[(1, 2, 3, 4), (5, 6, 7, 8)]
>>> reshape(seq, (2, [2])) # (i, i, [i, i])
[(1, 2, [3, 4]), (5, 6, [7, 8])]
>>> reshape(seq, ((2,), [2])) # etc....
[((1, 2), [3, 4]), ((5, 6), [7, 8])]
>>> reshape(seq, (1, [2], 1))
[(1, [2, 3], 4), (5, [6, 7], 8)]
>>> reshape(tuple(seq), ([[1], 1, (2,)],))
(([[1], 2, (3, 4)],), ([[5], 6, (7, 8)],))
>>> reshape(tuple(seq), ([1], 1, (2,)))
(([1], 2, (3, 4)), ([5], 6, (7, 8)))
>>> reshape(range(12), [2, [3], set([2]), (1, (3,), 1)])
[[0, 1, [2, 3, 4], set([5, 6]), (7, (8, 9, 10), 11)]]
"""
m = sum(flatten(how))
n, rem = divmod(len(seq), m)
if m < 0 or rem:
raise ValueError('template must sum to positive number '
'that divides the length of the sequence')
i = 0
container = type(how)
rv = [None]*n
for k in range(len(rv)):
rv[k] = []
for hi in how:
if type(hi) is int:
rv[k].extend(seq[i: i + hi])
i += hi
else:
n = sum(flatten(hi))
fg = type(hi)
rv[k].append(fg(reshape(seq[i: i + n], hi)[0]))
i += n
rv[k] = container(rv[k])
return type(seq)(rv)
Diff to Previous Revision
--- revision 1 2012-09-14 07:25:33
+++ revision 2 2012-10-23 20:34:18
@@ -1,44 +1,58 @@
def reshape(seq, how):
"""Reshape the sequence according to the template in ``how``.
+
+ Examples
+ ========
+
+ >>> from sympy.utilities import reshape
>>> seq = range(1, 9)
+
>>> reshape(seq, [4]) # lists of 4
[[1, 2, 3, 4], [5, 6, 7, 8]]
+
>>> reshape(seq, (4,)) # tuples of 4
[(1, 2, 3, 4), (5, 6, 7, 8)]
- >>> reshape(seq, (2,2)) # tuples of 4
+
+ >>> reshape(seq, (2, 2)) # tuples of 4
[(1, 2, 3, 4), (5, 6, 7, 8)]
- >>> reshape(seq, (2,[2])) # (i, i, [i, i])
+
+ >>> reshape(seq, (2, [2])) # (i, i, [i, i])
[(1, 2, [3, 4]), (5, 6, [7, 8])]
- >>> reshape(seq, ((2,),[2])) # etc....
+
+ >>> reshape(seq, ((2,), [2])) # etc....
[((1, 2), [3, 4]), ((5, 6), [7, 8])]
- >>> reshape(seq, (1,[2],1))
+
+ >>> reshape(seq, (1, [2], 1))
[(1, [2, 3], 4), (5, [6, 7], 8)]
- >>> reshape(tuple(seq), ([[1],1,(2,)],))
+
+ >>> reshape(tuple(seq), ([[1], 1, (2,)],))
(([[1], 2, (3, 4)],), ([[5], 6, (7, 8)],))
- >>> reshape(tuple(seq), ([1],1,(2,)))
+
+ >>> reshape(tuple(seq), ([1], 1, (2,)))
(([1], 2, (3, 4)), ([5], 6, (7, 8)))
+
+ >>> reshape(range(12), [2, [3], set([2]), (1, (3,), 1)])
+ [[0, 1, [2, 3, 4], set([5, 6]), (7, (8, 9, 10), 11)]]
+
"""
- def flatten(seq):
- rv = []
- for s in seq:
- if type(s) in (list, tuple):
- rv.extend(flatten(s))
- else:
- rv.append(s)
- return rv
+ m = sum(flatten(how))
+ n, rem = divmod(len(seq), m)
+ if m < 0 or rem:
+ raise ValueError('template must sum to positive number '
+ 'that divides the length of the sequence')
i = 0
- f = type(how)
- rv = [None]*(len(seq)//sum(flatten(how)))
+ container = type(how)
+ rv = [None]*n
for k in range(len(rv)):
rv[k] = []
- for gi in g:
- if type(gi) is int:
- rv[k].extend(seq[i: i + gi])
- i += gi
+ for hi in how:
+ if type(hi) is int:
+ rv[k].extend(seq[i: i + hi])
+ i += hi
else:
- n = sum(flatten(gi))
- fg = type(gi)
- rv[k].append(fg(reshape(seq[i: i + n], gi))[0])
+ n = sum(flatten(hi))
+ fg = type(hi)
+ rv[k].append(fg(reshape(seq[i: i + n], hi)[0]))
i += n
- rv[k] = f(rv[k])
+ rv[k] = container(rv[k])
return type(seq)(rv)