【问题标题】:How to extract the n-th elements from a list of tuples如何从元组列表中提取第 n 个元素
【发布时间】:2011-03-19 11:55:28
【问题描述】:

我正在尝试从元组列表中获取第 n 个元素。

我有类似的东西:

elements = [(1,1,1),(2,3,7),(3,5,10)]

我希望只将每个元组的第二个元素提取到一个列表中:

seconds = [1, 3, 5]

我知道这可以通过 for 循环来完成,但我想知道是否还有其他方法,因为我有数千个元组。

【问题讨论】:

    标签: python list tuples


    【解决方案1】:
    n = 1 # N. . .
    [x[n] for x in elements]
    

    【讨论】:

      【解决方案2】:

      这也有效:

      zip(*elements)[1]
      

      (我发这个主要是为了证明我已经摸到了zip...)

      查看实际操作:

      >>> help(zip)
      

      帮助builtin模块中的内置函数zip:

      压缩(...)

      zip(seq1 [, seq2 [...]]) -> [(seq1[0], seq2[0] ...), (...)]

      返回一个元组列表,其中每个元组包含第 i 个元素 从每个参数序列。返回的列表被截断 长度为最短参数序列的长度。

      >>> elements = [(1,1,1),(2,3,7),(3,5,10)]
      >>> zip(*elements)
      [(1, 2, 3), (1, 3, 5), (1, 7, 10)]
      >>> zip(*elements)[1]
      (1, 3, 5)
      >>>
      

      我今天学到的一件好事:在参数中使用*list 为函数创建参数列表...

      注意:在 Python3 中,zip 返回一个迭代器,因此请改用 list(zip(*elements)) 返回一个元组列表。

      【讨论】:

      • 并使用**dict 创建关键字参数:def test(foo=3, bar=3): return foo*bar 然后d = {'bar': 9, 'foo'=12}; print test(**d)
      • @Wayne Werner:是的。这些东西都只是被动知识(我不经常使用它)-但不时提醒一下很好,这样你就知道在哪里/要寻找什么......
      • 真实故事 - 我发现在我经常使用的任何东西(Python、vim)中,我往往需要提醒我已经忘记的整洁/酷炫的功能,因为我不使用它们 那个经常。
      • *list 语法非常有用。知道这在官方 python 文档中的描述吗?
      • 教程里才找到的:docs.python.org/2/tutorial/…
      【解决方案3】:

      我知道可以用 FOR 来完成,但我想知道是否有其他方法

      还有另一种方法。你也可以通过mapitemgetter 来实现:

      >>> from operator import itemgetter
      >>> map(itemgetter(1), elements)
      

      这仍然在内部执行一个循环,它比列表理解稍慢:

      setup = 'elements = [(1,1,1) for _ in range(100000)];from operator import itemgetter'
      method1 = '[x[1] for x in elements]'
      method2 = 'map(itemgetter(1), elements)'
      
      import timeit
      t = timeit.Timer(method1, setup)
      print('Method 1: ' + str(t.timeit(100)))
      t = timeit.Timer(method2, setup)
      print('Method 2: ' + str(t.timeit(100)))
      

      结果:

      方法一:1.25699996948 方法二:1.46600008011

      如果您需要遍历一个列表,那么使用 for 就可以了。

      【讨论】:

      • 一个小补充:在 python-3.x 中,基准测试将显示 map 只需要几分之一毫秒。那是因为它将返回一个迭代器。 method2 = 'list(map(itemgetter(1), elements))' 呈现旧的行为。
      【解决方案4】:

      在我搜索哪种方式可以最快地提取 2 元组列表的第二个元素时发现了这一点。不是我想要的,但运行与第三种方法相同的测试并测试 zip 方法

      setup = 'elements = [(1,1) for _ in range(100000)];from operator import itemgetter'
      method1 = '[x[1] for x in elements]'
      method2 = 'map(itemgetter(1), elements)'
      method3 = 'dict(elements).values()'
      method4 = 'zip(*elements)[1]'
      
      import timeit
      t = timeit.Timer(method1, setup)
      print('Method 1: ' + str(t.timeit(100)))
      t = timeit.Timer(method2, setup)
      print('Method 2: ' + str(t.timeit(100)))
      t = timeit.Timer(method3, setup)
      print('Method 3: ' + str(t.timeit(100)))
      t = timeit.Timer(method4, setup)
      print('Method 4: ' + str(t.timeit(100)))
      
      Method 1: 0.618785858154
      Method 2: 0.711684942245
      Method 3: 0.298138141632
      Method 4: 1.32586884499
      

      如果你有一个 2 元组对来转换为 dict 并获取值,那么速度会快两倍。

      【讨论】:

      • 这可能很明显,但我会提到dict(elements).values() 将导致单元素字典,而不是列表综合或映射。这正是我想要的(我对独特的 touples 感兴趣)(+1 非常感谢您的发帖)但其他人可能想知道为什么 dict 更快 - 它不是分配内存,而是仅检查现有元素。
      【解决方案5】:

      Python 3.6 的时序,用于从 2 元组列表中提取第二个元素。

      另外,添加了numpy数组方法,它更易于阅读(但可以说比列表理解更简单)。

      from operator import itemgetter
      elements = [(1,1) for _ in range(100000)]
      
      %timeit second = [x[1] for x in elements]
      %timeit second = list(map(itemgetter(1), elements))
      %timeit second = dict(elements).values()
      %timeit second = list(zip(*elements))[1]
      %timeit second = np.array(elements)[:,1]
      

      还有时间:

      list comprehension:  4.73 ms ± 206 µs per loop
      list(map):           5.3 ms ± 167 µs per loop
      dict:                2.25 ms ± 103 µs per loop
      list(zip)            5.2 ms ± 252 µs per loop
      numpy array:        28.7 ms ± 1.88 ms per loop
      

      请注意,map()zip() 不再返回列表,因此进行了显式转换。

      【讨论】:

      • dict().values() 也需要list
      • @Oleg 我不明白在 'dict` 方法中代码如何理解我们想要查看第二个元素。它是 values == 1 中的默认值吗?比如说,需要对第 3 个或第 10 个元素做同样的事情。 dict 方法有什么变化?
      【解决方案6】:
      map (lambda x:(x[1]),elements)
      

      【讨论】:

      • 考虑添加一些解释。
      【解决方案7】:

      使用islicechain.from_iterable

      >>> from itertools import chain, islice
      >>> elements = [(1,1,1),(2,3,7),(3,5,10)]
      >>> list(chain.from_iterable(islice(item, 1, 2) for item in elements))
      [1, 3, 5]
      

      当您需要多个元素时,这会很有用:

      >>> elements = [(0, 1, 2, 3, 4, 5), 
                      (10, 11, 12, 13, 14, 15), 
                      (20, 21, 22, 23, 24, 25)]
      >>> list(chain.from_iterable(islice(tuple_, 2, 5) for tuple_ in elements))
      [2, 3, 4, 12, 13, 14, 22, 23, 24]
      

      【讨论】:

        猜你喜欢
        • 2020-09-29
        • 2018-04-17
        • 1970-01-01
        • 1970-01-01
        • 2018-02-07
        • 2013-04-29
        • 1970-01-01
        • 2022-07-24
        • 1970-01-01
        相关资源
        最近更新 更多