Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/misc/flatten.py
4045 views
1
import sys
2
def flatten(in_list, ltypes=(list, tuple), max_level=sys.maxint):
3
"""
4
Flattens a nested list.
5
6
INPUT:
7
in_list -- a list or tuple
8
ltypes -- optional list of particular types to flatten
9
max_level -- the maximum level to flatten
10
11
OUTPUT:
12
a flat list of the entries of in_list
13
14
EXAMPLES:
15
sage: flatten([[1,1],[1],2])
16
[1, 1, 1, 2]
17
sage: flatten([[1,2,3], (4,5), [[[1],[2]]]])
18
[1, 2, 3, 4, 5, 1, 2]
19
sage: flatten([[1,2,3], (4,5), [[[1],[2]]]],max_level=1)
20
[1, 2, 3, 4, 5, [[1], [2]]]
21
sage: flatten([[[3],[]]],max_level=0)
22
[[[3], []]]
23
sage: flatten([[[3],[]]],max_level=1)
24
[[3], []]
25
sage: flatten([[[3],[]]],max_level=2)
26
[3]
27
28
29
In the following example, the vector isn't flattened because
30
it is not given in the ltypes input.
31
sage: flatten((['Hi',2,vector(QQ,[1,2,3])],(4,5,6)))
32
['Hi', 2, (1, 2, 3), 4, 5, 6]
33
34
We give the vector type and then even the vector gets flattened:
35
sage: flatten((['Hi',2,vector(QQ,[1,2,3])], (4,5,6)), ltypes=(list, tuple,sage.modules.vector_rational_dense.Vector_rational_dense))
36
['Hi', 2, 1, 2, 3, 4, 5, 6]
37
38
We flatten a finite field.
39
sage: flatten(GF(5))
40
[0, 1, 2, 3, 4]
41
sage: flatten([GF(5)])
42
[Finite Field of size 5]
43
sage: flatten([GF(5)], ltypes = (list, tuple, sage.rings.finite_rings.finite_field_prime_modn.FiniteField_prime_modn))
44
[0, 1, 2, 3, 4]
45
46
Degenerate cases:
47
sage: flatten([[],[]])
48
[]
49
sage: flatten([[[]]])
50
[]
51
"""
52
index = 0
53
current_level = 0
54
new_list = [x for x in in_list]
55
level_list = [0]*len(in_list)
56
57
while index < len(new_list):
58
len_v=None
59
while isinstance(new_list[index], ltypes) and current_level<max_level:
60
v = list(new_list[index])
61
len_v = len(v)
62
new_list[index : index + 1] = v
63
old_level = level_list[index]
64
level_list[index : index + 1] = [0]*len_v
65
if len_v != 0:
66
current_level += 1
67
level_list[index + len_v - 1] = old_level + 1
68
else:
69
current_level -= old_level
70
index -=1
71
break
72
73
# If len_v==0, then index points to a previous element, so we
74
# don't need to do anything.
75
if len_v!=0:
76
current_level -= level_list[index]
77
index += 1
78
return new_list
79
80