【问题标题】:python function yields tuple and only one element is wantedpython函数产生元组,只需要一个元素
【发布时间】:2016-12-08 22:10:26
【问题描述】:

我有一个功能

def f():
    # whatever
    yield (a,b)

现在我想收集所有a 但不是b。另外我希望结果aa 是一个列表而不是迭代器。现在我用

aa, _ = zip(*f())

就空间/时间效率而言,这是最好的吗?

【问题讨论】:

    标签: python tuples generator yield


    【解决方案1】:

    zip(*seq) 必须摄取整个生成器,然后才能输出列。这效率不高。

    只要坚持列表理解即可。你可以使用元组赋值:

    aa = [a for a, _ in f()]
    

    或使用索引:

    aa = [tup[0] for tup in f()]
    

    如果您没有必须让所有值可用于随机访问或其他必须具有列表的操作,则可以使用生成器表达式来保持内存效率:

    aa = (a for a, _ in f())
    

    【讨论】:

      【解决方案2】:

      您可以使用获取第一个返回项目的列表推导

      aa = [result[0] for result in f()]
      

      【讨论】:

        【解决方案3】:

        如果不修改f,你不能让它只产生元组的一个元素。但是,您可以轻松地链接生成器,例如使用生成器表达式:

        just_a_please = (a for a,b in f())
        

        要一次性使用所有 a,您应该更喜欢列表推导:

        all_a = [a for a,b in f()]
        

        如果你只想要其中一个,有next

        give_me_an_a, _b = next(f())
        

        【讨论】:

          【解决方案4】:

          很简单,你可以使用列表推导得到一个包含全部内容的列表

          aa = [ a for a,_ in f() ]
          

          【讨论】:

            【解决方案5】:

            对于使用operator 模块的解决方案:

            from operator import itemgetter
            get_first = itemgetter(0)
            aa = [get_first(x) for x in f()]
            

            编辑:我最初声明“使用operator 模块的有效解决方案”,但我找不到任何证据表明它比标准列表理解方法更有效。

            一些轶事%timeit观察:

            def f():
                for i in xrange(0, 10000):
                    yield (i, i ** i)
            
            def operator_way():
                return [get_first(x) for x in f()]
            
            def tuple_unpack_way():
                return [a for a, _ in f()]
            
            def indexing_way():
                return [a[0] for a in f()]
            
            def map_way():
                return map(get_first, f())
            

            %timeit operator_way() # 100 loops, best of 3: 9.25 ms per loop
            

            %timeit tuple_unpack_way() # 100 loops, best of 3: 9.28 ms per loop
            

            %timeit indexing_way() # 100 loops, best of 3: 9.17 ms per loop
            

            %timeit map_way() # 100 loops, best of 3: 9.07 ms per loop
            

            它们看起来或多或少是等价的。地图的效率可能会稍微高一些。

            【讨论】:

            • 你也可以测试:[x[0] for x in f()]
            • @DanD。好决定。也为此添加了一个测试。
            猜你喜欢
            • 2023-03-20
            • 2020-05-28
            • 2017-03-18
            • 2010-12-02
            • 2021-10-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多