递归分解列表以"atomic list"



我在python中嵌套列表列表(这是geojson坐标的结构)

这里有一个例子

更新后的示例以避免混淆

DictofCoordinates = {
'a': [1,1],
'b': [[2, 2], [2,2], [2, 2]],
'c': [[[3,3], [3, 3], [3, 3]]],
'd': [[[41, 41], [41, 41]], 
  [[42, 42], [42, 42]]]
 }

我想要得到的是除了(坐标)对之外不包含任何其他内容的列表。这就是我所说的"列表的原子列表"(因为没有更好的术语)

 - for a : the list  [1, 1]
 - for b : [[2, 2], [2,2], [2, 2]]
 - for c : [[3,3], [3, 3], [3, 3]]
 - for d : the two lists [[41, 41], [41, 41]] and  [[42, 42], [42, 42]]]

从这里获得灵感这就是我所尝试的

def ExplodeTolist(xList):
for x1 in xList:
    if isinstance(x1[0], (float, int, long)):
        yield x1
    else:
        for x2 in ExplodeTolist(x1):
            yield x2 

但是不工作

for x in ExplodeTolist(DictofCoordinates.values()):
   print x        

感谢任何帮助。由于

如果我理解正确,您只是想处理每个列表的内容,如果它包含更多列表。否则,您希望返回列表本身。我认为你犯的最大的错误是你的函数是递归的,所以它尽可能地深入,最终你得到的只是一个遍历所有点的迭代器。试试这个:

# You might want to modify this method to
# return False if it passes isinstance(x, basestring)
def is_iterable(x):
    try:
        iter(x)
        return True
    except TypeError:
        return False
def get_elements(coordinate_dict):
    for v in coordinate_dict.values():
        if is_iterable(v[0]):
            for i in v:
                yield i
        else:
            yield v

当它找到可迭代的内容时,它遍历列表并返回元素。如果列表的内容不是可迭代的,它只返回列表。关键的区别在于,当它找到可迭代的内容时,它只迭代一层深度

正如在评论中看到的,关于如何测试某些东西是否可迭代存在一些争论。在Python中,我如何确定一个对象是否可迭代?以及它的答案,以便更多地讨论这个话题。

下面是输出。这有点乱,因为dict是无序的,但是所有的元素都在那里:

>>> for i in get_elements(d):
...      print i
...
[1, 1]
[[3, 3], [3, 3], [3, 3]]
[2, 2]
[2, 2]
[2, 2]
[[41, 41], [41, 41]]
[[42, 42], [42, 42]]

实际上只需要检查element[0]是否为列表。

def flatten(items):
    for elem in items:
        if isinstance(elem[0],list):
            for sub_elem in elem:
                yield sub_elem
        else:
            yield elem
print list(flatten(DictofCoordinates.values())) 
[[1, 1], [[3, 3], [3, 3], [3, 3]], [2, 2], [2, 2], [2, 2], [[41, 41], [41, 41]], [[42, 42], [42, 42]]]

匹配你的新输出:

def flatten(items):
    for elem in items:
        if sum(isinstance(i, list) for i in elem) == 0 or sum(isinstance(i, list) for i in elem[0]) == 0:
            yield elem
        else:
            for sub_elem in elem:
                yield sub_elem
print (list(flatten(DictofCoordinates.values())))
[[1, 1], [[3, 3], [3, 3], [3, 3]], [[2, 2], [2, 2], [2, 2]], [[41, 41], [41, 41]], [[42, 42], [42, 42]]]

这个函数将返回您所描述的原子。

def getAtoms(lst):
    for l in lst:
        yield l

最新更新