Python 从if any()获取迭代器

Python 从if any()获取迭代器,python,iterator,any,Python,Iterator,Any,我有一个简单的功能: keys = ['snmt1/metadata/table1/ref_table1_20190324124365.csv', 'snmt1/metadata/table2/table2_ref_20190324124365.csv', 'snmt1/metadata/table3/table3_20190324124365.csv'] def better_func(keys): for item in keys: split_key = item.spli

我有一个简单的功能:

keys = ['snmt1/metadata/table1/ref_table1_20190324124365.csv', 'snmt1/metadata/table2/table2_ref_20190324124365.csv', 'snmt1/metadata/table3/table3_20190324124365.csv']


def better_func(keys):
  for item in keys:
    split_key = item.split("/")
    filename = str(split_key[-1])
    prefixes = ['strm','ref','trunc']
    if any(x in filename for x in prefixes):
      location = filename.find(x)
      if location == 0:
        print True
      else:
        print "another false"
    else:
      print False
我需要的是x的值,这样我就可以用.find函数返回它的索引。上面的代码不起作用,因为它告诉我:

NameError:未定义全局名称“x”

我明白,但我如何才能像通常在for循环中那样访问x

for x in my_list:
    print x
而不是

if any(x in filename for x in prefixes):
    # do stuff with x
你可以做:

x = next((p for p in prefixes if p in filename), None)
if x:
    # do stuff with x
这将创建一个生成器,并从中获取下一个值,即第一个值。 None的第二个参数是sentinel值:如果迭代器引发StopIteration,而不是传递此异常,则返回None,并绑定到x

这在这里看起来并不是很有用,但当您需要满足条件的序列的第一个元素,并且如果没有这样的元素,则需要回退操作时,它确实很方便:

elt = next((x for x in range(10) if x > 5), None)
if elt is not None:
    print("{} satisfies the condition".format(elt))
else:
    print("No such element found")
请注意,生成器也是迭代器,所以您可以直接调用它们上的next。对于类似列表、dict或其他任何内容的iter,您需要首先调用iter。例如,从字典中获取任意值非常有用:

value = next(iter(d.values()))
而不是

if any(x in filename for x in prefixes):
    # do stuff with x
你可以做:

x = next((p for p in prefixes if p in filename), None)
if x:
    # do stuff with x
这将创建一个生成器,并从中获取下一个值,即第一个值。 None的第二个参数是sentinel值:如果迭代器引发StopIteration,而不是传递此异常,则返回None,并绑定到x

这在这里看起来并不是很有用,但当您需要满足条件的序列的第一个元素,并且如果没有这样的元素,则需要回退操作时,它确实很方便:

elt = next((x for x in range(10) if x > 5), None)
if elt is not None:
    print("{} satisfies the condition".format(elt))
else:
    print("No such element found")
请注意,生成器也是迭代器,所以您可以直接调用它们上的next。对于类似列表、dict或其他任何内容的iter,您需要首先调用iter。例如,从字典中获取任意值非常有用:

value = next(iter(d.values()))

将于2019年底发布的Python 3.8将提供赋值表达式,部分是为了解决命名任何人成功的见证人的确切用例

import os


def better_func(keys):
    prefixes = ['strm', 'ref', 'trunk']
    for item in keys:
        filename = os.path.basename(item)
        if any((found := x) for x in prefix if x in filename):
           if filename.startswith(found):
               print True
           else:
               print "another false"
        else:
           print False

将于2019年底发布的Python 3.8将提供赋值表达式,部分是为了解决命名任何人成功的见证人的确切用例

import os


def better_func(keys):
    prefixes = ['strm', 'ref', 'trunk']
    for item in keys:
        filename = os.path.basename(item)
        if any((found := x) for x in prefix if x in filename):
           if filename.startswith(found):
               print True
           else:
               print "another false"
        else:
           print False

你想要下一个吗?你能再解释一下吗。添加next如何帮助我返回x的值?Any在这里是正确的函数,它按预期工作,我只需要在前缀中访问x的值。findx=nextx for x如果x在filename中,则为None:如果x:或者可能是filename.startswithx-假设您想要第一个,请使用列表compmathces@Chris_Rands除了上一次迭代之外,这是有效的,然后它抛出一个错误回溯最后一个最近的调用:File main.py,第78行,在better_funckeys File main.py,第26行,在better_func if filename.startswithx:TypeError:startswith first arg必须是str、unicode或tuple,而不是noneType我可以将None的值更改为默认值,但这看起来不是很pythonic,为了满足最后一次迭代。这就是问题所在,对吗?你想要下一个,不是吗?你能再解释一下吗。添加next如何帮助我返回x的值?Any在这里是正确的函数,它按预期工作,我只需要在前缀中访问x的值。findx=nextx for x如果x在filename中,则为None:如果x:或者可能是filename.startswithx-假设您想要第一个,请使用列表compmathces@Chris_Rands除了上一次迭代之外,这是有效的,然后它抛出一个错误回溯最后一个最近的调用:File main.py,第78行,在better_funckeys File main.py,第26行,在better_func if filename.startswithx:TypeError:startswith first arg必须是str、unicode或tuple,而不是noneType我可以将None的值更改为默认值,但这看起来不是很pythonic,为了满足最后一次迭代。这就是问题所在,对吗?x只是这里的第一个前缀,不是我想要的,我试过了,但效果不理想。它返回的值为falsekeys@William我的坏,我修复了这个你不需要iter;接下来…,你是第三块代码,这是我最后实现的。我最初每次都通过try:except:block从下一个函数捕获StopIteration,但是使用默认值设置为None并将其放入if语句中的解决方案更为优雅x只是这里的第一个前缀,而不是所需的前缀。我尝试了这个方法,但没有按照预期工作。它返回的值为falsekeys@William我的坏,我修复了这个你不需要iter;接下来…,你是第三块代码,这是我最后实现的。我最初每次都通过try:except:block从下一个函数捕获StopIteration,但是您使用默认值设置为None并将其放入if语句中的解决方案可能更为优雅,从技术上讲,这将不会指定与要查找的条件相匹配的x的第一个值,但是,所有的值,包括第一个值,有点像一个漏洞百出的列表。而且,找到它也需要时间
如果所有元素都不满足条件,则返回x的最后一个值;我想现在已经修好了。我不确定found是否设置为以前的值是否重要,但是,因为您无法访问任何值之外的值,也就是说,直到any本身返回。可能值得注意的是,从技术上讲,这不会指定与要查找的条件匹配的x的第一个值,而是指定第一个值之前的所有值,有点像漏洞百出的清单。此外,如果没有任何元素满足条件,find将采用最后一个值x;我想现在已经修好了。不过,我不确定find是否设置为以前的值是否重要,因为在any本身返回之前,您无法访问其值以外的值。