高效迭代Python嵌套列表

6

我正在使用Python开发一个网络流量监控项目。由于对Python不是很熟悉,所以在这里寻求帮助。

简而言之,我正在检查进出流量,我是这样写的:

for iter in ('in','out'):
        netdata = myhttp()
        print data

netdata是一个由嵌套列表组成的列表,其格式如下:

[ [t1,f1], [t2,f2], ...]

这里的t代表时间,f是流量。然而,我现在想要保持这些f在进出两个方向上的一致性,我想知道是否有一种高效的方法来实现。
经过一番搜索,我认为我需要创建一个交通列表(2个元素),然后使用zip函数同时迭代这两个列表,但我很难写出正确的代码。由于我的netdata是一个非常长的列表,效率也非常重要。
如果有任何不清楚的地方,请告诉我,我会尽力澄清。 感谢帮助。
3个回答

14

除了@Zero Piraeus提出的问题之外,您的代码需要进行一些小修补,您的问题可能已经在这里得到了解答。以下是一个可能用于遍历N层(树状结构)列表的代码:

def traverse(item):
    try:
        for i in iter(item):
            for j in traverse(i):
                yield j
    except TypeError:
        yield item

例子:

l = [1, [2, 3], [4, 5, [[6, 7], 8], 9], 10]
print [i for i in traverse(l)]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

让它工作的关键是递归,让它高效工作的关键是使用生成器(关键字 yield 提供了提示)。生成器将遍历您的列表中的子列表,逐个返回项,而无需复制数据或创建整个新列表(除非您消耗整个生成器并将结果分配给列表,就像我的示例一样)。

使用迭代器和生成器可能是一些难以理解的概念(主要是关键字 yield)。查看这个很棒的回答,可以完全理解它们。


1

你展示的代码并没有太多意义。以下是它的作用:

  • 遍历序列'in', 'out',在循环的两次迭代中依次将这两个字符串分配给变量iter(在此过程中掩盖了内置函数iter())。

  • 完全忽略循环内iter的值。

  • 在每次循环中将myhttp()的结果分配给变量netdata

  • 完全忽略netdata的值,并尝试在每次循环中打印未定义的变量data

考虑到您描述的嵌套列表,可能需要像这样的代码:

for t, f in myhttp():
    print t
    print f
    # ... or whatever you want to do with those values.

0
尝试其他答案时,该函数无法递归,因此我修改了它以避免递归。它仍然非常快,并且可以处理大型嵌套列表(至少在我的测试中是这样)。这是一个仅适用于Python 3的函数。
# Originally by Bruno Polaco
def traverse(item, reverse=False):
    its = [item] #stack of items to-be-processed
    out = [] # Output (no longer generator)
    ite = False
    while len(its) > 0:
        it = its.pop()
        try: # Check if item is iterable
            iter(it)
            ite = not isinstance(it, str)
        except TypeError:
            ite = False
        if ite: # Do something with it
            for i in it:
                its.append(i)
        else:
            out.append(it)
    if not reverse:
        out.reverse()
    return out

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接