将`filter object`转换为`list`会清除其内容

时间:2013-07-24 15:09:32

标签: list python-3.x filter

在调查我的另一个问题时,我遇到了一种非常奇怪的行为。

运行代码:

def test(prefix, custom_meta_files = []):
  postfix = 'tgz'  
  if prefix[-1] != '.':
    postfix = '.tgz'

  archive = tarfile.open(prefix+postfix, "w:gz")
  files = filter(lambda path: path.startswith(prefix), os.listdir())
  print('files: {0}'.format(list(files)))
  print('files: {0}'.format(list(files)))


files: ['ga_run.seq_niche.N30.1.bt0_5K.params', 'ga_run.seq_niche.N30.1.bt0_5K.stats', 'ga_run.seq_niche.N30.1.bt0_5K.tgz']
files: []

似乎将filter object投射到list清除它。为什么这样,是否需要?

2 个答案:

答案 0 :(得分:1)

嗯......我可能会变得愚蠢。但我开始再次阅读文档,我想我  找出原因。我把它作为一个自我答案发布,因为我认为这个问题是有效的,不值得或删除。

Documentation说:“请注意,过滤器(函数,可迭代)等效于生成器表达式(如果函数(项目),则迭代中的项目项目)如果函数不是None,则(项目中的项目可迭代,如果item)如果函数为None。“

因此,如果它充当发电机,可能会将其迭代在发电机上并有效地“清空”它。

但是,如果有任何python专家可以指出这是否是正确的思维方式,我将不胜感激。

答案 1 :(得分:0)

执行此操作时:

list(files)

你有效地使用filter返回的生成器来创建列表(顺便说一下它不是“强制转换”),所以第二次写list(files)时,生成器已经完成了。这应该解决它,并且将重复结果存储在变量中也是一个好主意 - 它避免重新计算值:

lst = list(files)
print('files: {0}'.format(lst))
print('files: {0}'.format(lst))