Welcome to mirror list, hosted at ThFree Co, Russian Federation.

collapse.py « utils « mcf « modules « python « intern - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 25da50c2adbe38bf37540e485fb7fa74b849fe94 (plain)
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
'''
Destructive Functions for "collapsing" Sequences into single levels

>>> from mcf.utils import collapse

>>> collapse.test([[[1],[2,3]],[[]],[4],5,[6]])

[1, 2, 3, 4, 5, 6] # note that is the same root list

>>> collapse.collapse2([[[1],[2,3]],[[]],(4,()),(5,),[6]])

[1, 2, 3, 4, 5, 6] # note is the same root list
'''
import copy, types, sys
from types import ListType, TupleType # this now only supports the obsolete stuff...

def hyperCollapse( inlist, allowedmap, type=type, list=list, itype=types.InstanceType, maxint= sys.maxint):
	'''
	Destructively flatten a mixed hierarchy to a single level.
	Non-recursive, many speedups and obfuscations by Tim Peters :)
	'''
	try:
		# for every possible index
		for ind in xrange( maxint):
			# while that index currently holds a list
			expandable = 1
			while expandable:
				expandable = 0
				if allowedmap.has_key( type(inlist[ind]) ):
					# expand that list into the index (and subsequent indicies)
					inlist[ind:ind+1] = list( inlist[ind])
					expandable = 1
				
				# alternately you could iterate through checking for isinstance on all possible
				# classes, but that would be very slow
				elif type( inlist[ind] ) is itype and allowedmap.has_key( inlist[ind].__class__ ):
					# here figure out some way to generically expand that doesn't risk
					# infinite loops...
					templist = []
					for x in inlist[ind]:
						templist.append( x)
					inlist[ind:ind+1] = templist
					expandable = 1
	except IndexError:
		pass
	return inlist
	

def collapse(inlist, type=type, ltype=types.ListType, maxint= sys.maxint):
	'''
	Destructively flatten a list hierarchy to a single level. 
	Non-recursive, and (as far as I can see, doesn't have any
	glaring loopholes).
	Further speedups and obfuscations by Tim Peters :)
	'''
	try:
		# for every possible index
		for ind in xrange( maxint):
			# while that index currently holds a list
			while type(inlist[ind]) is ltype:
				# expand that list into the index (and subsequent indicies)
				inlist[ind:ind+1] = inlist[ind]
			#ind = ind+1
	except IndexError:
		pass
	return inlist

def collapse_safe(inlist):
	'''
	As collapse, but works on a copy of the inlist
	'''
	return collapse( inlist[:] )

def collapse2(inlist, ltype=(types.ListType, types.TupleType), type=type, maxint= sys.maxint ):
	'''
	Destructively flatten a list hierarchy to a single level.
	Will expand tuple children as well, but will fail if the
	top level element is not a list.
	Non-recursive, and (as far as I can see, doesn't have any
	glaring loopholes).
	'''
	ind = 0
	try:
		while 1:
			while type(inlist[ind]) in ltype:
				try:
					inlist[ind:ind+1] = inlist[ind]
				except TypeError:
					inlist[ind:ind+1] = list(inlist[ind])
			ind = ind+1
	except IndexError:
		pass
	return inlist

def collapse2_safe(inlist):
	'''
	As collapse2, but works on a copy of the inlist
	'''
	return collapse( list(inlist) )
	
def old_buggy_collapse(inlist):
	'''Always return a one-level list of all the non-list elements in listin,
	rewritten to be non-recursive 96-12-28  Note that the new versions work
	on the original list, not a copy of the original.'''
	if type(inlist)==TupleType:
		inlist = list(inlist)
	elif type(inlist)!=ListType:
		return [inlist]
	x = 0
	while 1:
		try:
			y = inlist[x]
			if type(y) == ListType:
				ylen = len(y)
				if ylen == 1:
					inlist[x] = y[0]
					if type(inlist[x]) == ListType:
						x = x - 1 # need to collapse that list...
				elif ylen == 0:
					del(inlist[x])
					x = x-1 # list has been shortened
				else:
					inlist[x:x+1]=y
			x = x+1
		except IndexError:
			break
	return inlist


def old_buggy_collapse2(inlist):
	'''As collapse, but also collapse tuples, rewritten 96-12-28 to be non-recursive'''
	if type(inlist)==TupleType:
		inlist = list(inlist)
	elif type(inlist)!=ListType:
		return [inlist]
	x = 0
	while 1:
		try:
			y = inlist[x]
			if type(y) in [ListType, TupleType]:
				ylen = len(y)
				if ylen == 1:
					inlist[x] = y[0]
					if type(inlist[x]) in [ListType,TupleType]:
						x = x-1 #(to deal with that element)
				elif ylen == 0:
					del(inlist[x])
					x = x-1 # list has been shortened, will raise exception with tuples...
				else:
					inlist[x:x+1]=list(y)
			x = x+1
		except IndexError:
			break
	return inlist


def oldest_buggy_collapse(listin):
	'Always return a one-level list of all the non-list elements in listin'
	if type(listin) == ListType:
		return reduce(lambda x,y: x+y, map(collapse, listin), [])
	else: return [listin]

def oldest_buggy_collapse2(seqin):

	if type(seqin) in [ListType, TupleType]:
		return reduce(lambda x,y: x+y, map(collapse2, seqin), [])
	else:
		return [seqin]