我有这种结构:
[
array([ 0. , 4.5, 9. ]),
[
array([ 100., 120., 140.]),
[
array([ 1000., 1100., 1200.]),
array([ 1200., 1300., 1400.])
],
array([ 150., 170., 190.]),
[
array([ 1500., 1600., 1700.]),
array([ 1700., 1800.])
]
]
]
(其中array
是numpy.array
s)
如何编写一个给我的生成器:
(0, 4.5), (100, 120), (1000, 1100)
(0, 4.5), (100, 120), (1100, 1200)
(0, 4.5), (120, 140), (1200, 1300)
(0, 4.5), (120, 140), (1300, 1400)
(4.5, 9), (150, 170), (1500, 1600)
(4.5, 9), (150, 170), (1600, 1700)
(4.5, 9), (170, 190), (1700, 1800)
到目前为止,我唯一的成就是:
def loop_bin(bins):
for i in range(len(bins)-1):
yield [bins[i], bins[i+1]]
答案 0 :(得分:2)
查看您的情况我将其分解为几种不同类型的迭代:overlap
和paired
(以及常规迭代)。
然后我在dopair
中递归遍历您的树结构,该结构分析类型以决定它应如何迭代它看到的数据。决定是基于我们是处理节点(包含子树)还是叶子(数组)。
generator
全力以赴。 izip
允许我们同时迭代两个生成器。
from itertools import izip
class array(list):
pass
arr = [
array([ 0. , 4.5, 9. ]),
[
array([100., 120., 140.]),
[
array([ 1000., 1100., 1200.]),
array([ 1200., 1300., 1400.])
],
array([ 150., 170., 190.]),
[
array([ 1500., 1600., 1700.]),
array([ 1700., 1800.])
]
]
]
# overlap(structure) -> [st, tr, ru, uc, ct, tu, ur, re]
def overlap(structure):
for i in range(len(structure)-1):
yield (structure[i],structure[i+1])
# paired(structure) -> [st, ru, ct, ur]
def paired(structure):
for i in range(0,len(structure)-1,2):
yield (structure[i],structure[i+1])
def dopair(first,second):
if all(isinstance(x,array) for x in second):
for pa,ir in izip(overlap(first),second):
for item in overlap(ir):
yield pa, item
else:
for pa,(i,r) in izip(overlap(first),paired(second)):
for item in dopair(i,r):
yield (pa,) + item
def generator(arr):
for pa,ir in paired(arr):
for x in dopair(pa,ir):
yield x
for x in generator(arr):
print x
答案 1 :(得分:1)
怎么样:
def foo(m):
for i in range(0, len(m), 2):
for j in range(len(m[i])-1):
current = tuple(m[i][j:(j+2)])
mm = m[i+1]
if(len(mm) % 2 != 0 or (len(mm) > 1 and not type(mm[1][0]) is types.ListType)):
currentl = mm[j]
for k in range(0, len(currentl)-1):
yield current, tuple(currentl[k:(k+2)])
else:
for res in foo(mm[2*j:2*j+2]):
# this is for pretty print only
if type(res) is types.TupleType and len(res)>1 and not type(res[0]) is types.TupleType:
yield current, res
else:
# pretty print again
c = [current]
c+= res
yield tuple(c)
tuple
内容非常适合打印,以便更贴近您的示例。我不太确定用于检测叶子的标准。另请注意,我使用以下pythonic数组进行了实验:
arr = [
[ 0. , 4.5, 9. ],
[
[100., 120., 140.],
[
[ 1000., 1100., 1200.],
[ 1200., 1300., 1400.]
],
[ 150., 170., 190.],
[
[ 1500., 1600., 1700.],
[ 1700., 1800.]
]
]
]
而不是给出的numpy数组,但使用numarray运行的更改应该是直截了当的。
答案 2 :(得分:0)
使用递归来执行此操作:
def foo( lst, path ):
if type(lst[0]) != type(array([])):
return [path+[(lst[0],lst[1])], path+[(lst[1],lst[2])]]
i = 0
ret = []
while i < len(lst):
node = lst[i]
successor = lst[i+1] if i+1<len(lst) else None
if type(node) == type(array([])):
if type(successor) == list:
children = successor
ret.extend( foo( children, path + [(node[0], node[1])] ) )
ret.extend( foo( children, path + [(node[1], node[2])] ) )
i+=1
else:
ret.append( path + [(node[0], node[1])] )
ret.append( path + [(node[1], node[2])] )
i+=1
return ret
致电foo( input, [] )
进行计算。