在python中迭代未清除的维度数组

在python中迭代未清除的维度数组,python,generator,Python,Generator,我有一些多维数组,如下所示: a= [[1,2],[2,4],[31,2]] b= [[[1,2],[2,4],[31,2]],[[22,34],[322,323],[3454,544]]] c= [[[[1,2],[2,4],[31,2]],[[22,34],[322,323],[3454,544]]],[[[1,2],[2,4],[31,2]],[[22,34],[322,323],[3454,544]]]] for x,y in flatten(ary): return x,y-

我有一些多维数组,如下所示:

a= [[1,2],[2,4],[31,2]]

b= [[[1,2],[2,4],[31,2]],[[22,34],[322,323],[3454,544]]]

c= [[[[1,2],[2,4],[31,2]],[[22,34],[322,323],[3454,544]]],[[[1,2],[2,4],[31,2]],[[22,34],[322,323],[3454,544]]]]
for x,y in flatten(ary):
  return x,y-x
现在我想将每个[x,y]对的值更改为[x,y-x],所需结果:

a= [[1,0],[2,2],[31,-29]]    ==> [1,0] =  [1,(1-0)]
我试着像这样使用生成器(受此启发):

但它并没有像预期的那样起作用

如何修复它

注:

例如,可以相应地改变将
[x,y]转换为[x,y-x]
的操作

[x,y]==>[x,x*y]
可能是另一个操作

因此,我不想将操作硬编码到迭代中

我想要这样的东西:

a= [[1,2],[2,4],[31,2]]

b= [[[1,2],[2,4],[31,2]],[[22,34],[322,323],[3454,544]]]

c= [[[[1,2],[2,4],[31,2]],[[22,34],[322,323],[3454,544]]],[[[1,2],[2,4],[31,2]],[[22,34],[322,323],[3454,544]]]]
for x,y in flatten(ary):
  return x,y-x
如果有必要,我只需将其更改为:

for x,y in flatten(ary):
  return x,y+x  # any operation I want

这里有一种方法——它是一个递归函数,在每一个级别上,如果你有一个列表列表,你会发现,如果你有一个列表列表列表,那么递归会更深。如果有元素列表,请执行(x,y)=(x,y-x)转换

a= [[1,2],[2,4],[31,2]]

b= [[[3,3],[22,542]]]

c= [[[[1,33],[5,88]]]]

def flatten(l):
    for i, e in enumerate(l):
        if type(e) is list and type(e[0]) is list:
            flatten(e)
        else:
            x, y = e
            l[i] = (x, y-x)

>>> flatten(a)
[(1, 1), (2, 2), (31, -29)]
>>> flatten(b)
[[(3, 0), (22, 520)]]
>>> flatten(c)
[[[(1, 31), (5, 78)]]]
使用:

有了它,您可以:

>>> for x, y in chunks(2, iflatten(any)):
...     # your operations

我只是在代码下面改进了Martin Konecny的答案

def flatten(array, operation):

    for i, e in enumerate(array):
        if isinstance(e, (list, tuple)) and isinstance(e[0], (list, tuple)):
            flatten(e, operation)
        elif isinstance(e, (int, float)):
            array[0], array[1] = operation(array[0], array[1])
            break
        else:
            array[i] = operation(e[0], e[1])

a= [[1,2],[2,4],[31,2]]

b= [[[1,2],[2,4],[31,2]],[[22,34],[322,323],[3454,544]]]

c= [[[[1,2],[2,4],[31,2]],[[22,34],[322,323],[3454,544]]],[[[1,2],[2,4],[31,2]],[[22,34],[322,323],[3454,544]]]]
演示的结果是:

>>> 
>>> flatten(a, lambda x, y: [x, y * x])
>>> a
[[1, 2], [2, 8], [31, 62]]
>>> flatten(b, lambda x, y: [x, y - x])
>>> b
[[[1, 1], [2, 2], [31, -29]], [[22, 12], [322, 1], [3454, -2910]]]
>>> flatten(c, lambda x, y: [x, y + x])
>>> c
[[[[1, 3], [2, 6], [31, 33]], [[22, 56], [322, 645], [3454, 3998]]], [[[1, 3], [2, 6], [31, 33]], [[22, 56], [322, 645], [3454, 3998]]]]
>>> 
这是一个新的测试:

>>> 
>>> d = [1,2]
>>> flatten(d, lambda x, y: [x, y +5])
>>> d
[1, 7]
>>> 

希望,可以帮到你。

用另一种方法来做。只需在适当的水平停止展平:

from funcy import iflatten, is_list

follow = lambda l: is_list(l) and not is_list(l[0])
d = [(x, y - x) for x, y in iflatten(l, follow)]

向下投票者,请拿出**,告诉我为什么。这是递归解决方案,我想知道是否可以使用生成器?我认为生成器解决方案在这里不起作用-您希望在每次迭代中返回哪些元素?它是根级列表(仅一次迭代),还是每个“叶”列表(多次迭代,但不会嵌套在其他列表中)?应该返回的最深元素是坐标对,如[x,y]。请澄清,在链接到的展平解决方案中,它们提供了一个扁平列表,可以很好地在生成器上进行迭代。另一方面,您希望原始列表的结构保持不变,这与生成器冲突。您提供的链接实际上使用递归。如果您希望输出为平面列表,则可以使用生成器。如果我调用
flant([1,2],operation)
,如何?@hguser,我已经改进了我的答案。@hguser只想知道这是否是正确的答案,以便我可以改进答案。谢谢。我在尝试不同类型的数据。现在它可以工作了,谢谢你和@Martin Konecny。但是还有一个问题,如果lambda中需要一些额外的参数呢?你也可以在这里使用迭代器版本的
chunks
。如果你确定你有偶数的物品,最好使用。