被链式枚举所迷惑

2024-09-29 00:14:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我想把所有的头文件收集到一个子目录列表中。但是,如果我这样做了

from glob import glob
from itertools import chain

subDirs = ['FreeRTOS', 'Twig']
for each in chain(glob(eachDir+'/*.h') for eachDir in subDirs):
  print each

我得到的是

['FreeRTOS/croutine.h', 'FreeRTOS/FreeRTOS.h', 'FreeRTOS/FreeRTOSConfig.h', 'FreeRTOS/list.h', 'FreeRTOS/mpu_wrappers.h', 'FreeRTOS/portable.h', 'FreeRTOS/portmacro.h', 'FreeRTOS/projdefs.h', 'FreeRTOS/queue.h', 'FreeRTOS/semphr.h', 'FreeRTOS/StackMacros.h', 'FreeRTOS/task.h', 'FreeRTOS/timers.h']
['Twig/twig.h']

但我想看到的是

'FreeRTOS/croutine.h'
'FreeRTOS/FreeRTOS.h'
'FreeRTOS/FreeRTOSConfig.h'
'FreeRTOS/list.h'
'FreeRTOS/mpu_wrappers.h'
'FreeRTOS/portable.h'
'FreeRTOS/portmacro.h'
'FreeRTOS/projdefs.h'
'FreeRTOS/queue.h'
'FreeRTOS/semphr.h'
'FreeRTOS/StackMacros.h'
'FreeRTOS/task.h'
'FreeRTOS/timers.h'
'Twig/twig.h'

我以为这就是链子()对我的作用。我错过了什么?你知道吗


Tags: infromimportchainforgloblisteach
2条回答

我想你在找itertools.chain.from_iterable

import os
import glob
import itertools

for each in itertools.chain.from_iterable(
        glob.glob(os.path.join(eachDir,'/*.h')) 
        for eachDir in subDirs):
    print each

它压平了一堆难以忍受的东西:

In [6]: import itertools as IT
In [7]: list(IT.chain.from_iterable([['a', 'b', 'c'], [1, 2, 3]]))
Out[7]: ['a', 'b', 'c', 1, 2, 3]

可能比unutbu的答案慢,但这也会起作用:

import collections
def flattenIter(l):
    """
        Iterator that flattens a list by one each iteration
        To get a fully flattened list of L do:
            list(flattenIter(L))
    """
    for el in l:
        if isinstance(el, collections.Iterable) and not isinstance(el, basestring):
            for sub in flattenIter(el):
                yield sub
        else:
            yield el

请注意,与unutbu的回答相比,这会使列表中的列表数量变平,而不是他的方法。示例:

print list(IT.chain.from_iterable([['a', 'b', 'c'], [1, 2, 3],"aap",["beer",[1]]]))
# ['a', 'b', 'c', 1, 2, 3, 'a', 'a', 'p', 'beer', [1]]
print list(flattenIter([['a', 'b', 'c'], [1, 2, 3],1,"aap",["beer",[1]]]))
# ['a', 'b', 'c', 1, 2, 3, 1, 'aap', 'beer', 1]

和联合国大学的答案一样。你知道吗

In : list(flattenIter([['a', 'b', 'c'], [1, 2, 3]]))
Out: ['a', 'b', 'c', 1, 2, 3]

以下是与unutbu版本的速度比较:

import timeit
import collections
import time
import itertools as IT

class Timer:
    def __enter__(self):
        self.start = time.clock()
        return self

    def __exit__(self, *args):
        self.end = time.clock()
        self.interval = self.end - self.start

def flattenIter(l):
    """
        Iterator that flattens a list by one each iteration
        To get a fully flattened list of L do:
            list(flattenIter(L))
    """
    for el in l:
        if isinstance(el, collections.Iterable) and not isinstance(el, basestring):
            for sub in flattenIter(el):
                yield sub
        else:
            yield el

with Timer() as t:
    for x in xrange(10000):
        list(IT.chain.from_iterable([['a', 'b', 'c'], [1, 2, 3]]))

print t.interval
# result: 0.0220727116414

with Timer() as t:
    for x in xrange(10000):
        list(flattenIter([['a', 'b', 'c'], [1, 2, 3]]))

print t.interval
# result: 0.147218201587

还可以查看:

Making a flat list out of list of lists in Python

它被标记为复制,尽管它还有一些其他的实体链接。;)

相关问题 更多 >