代码之家  ›  专栏  ›  技术社区  ›  pleasedontbelong

如何从元组列表中提取n个元素?

  •  81
  • pleasedontbelong  · 技术社区  · 16 年前

    我试图从元组列表中获取第n个元素。

    我有点像:

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

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

    seconds = [1, 3, 5]
    

    我知道可以用 for 循环,但我想知道是否还有其他方法,因为我有数千个元组。

    7 回复  |  直到 16 年前
        1
  •  151
  •   cs95 abhishek58g    7 年前
    n = 1 # N. . .
    [x[n] for x in elements]
    
        2
  •  26
  •   Mark Byers    16 年前

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

    还有另一种方法。你也可以用 map itemgetter :

    >>> 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)))
    

    结果:

    Method 1: 1.25699996948
    Method 2: 1.46600008011
    

    如果需要遍历列表,则使用 for 很好。

        3
  •  25
  •   jpp    7 年前

    这也适用于:

    zip(*elements)[1]
    

    (我主要是把这个贴出来,向自己证明我已经摸索过了 zip ……)

    见效:

    >>> help(zip)
    

    关于内置函数zip-in模块的帮助 内建 :

    拉链(…)

    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 在参数中为函数创建参数列表…

    注释 在Python 3中, 拉链 返回迭代器,因此改用 list(zip(*elements)) 返回元组列表。

        4
  •  11
  •   Graeme Gellatly    13 年前

    我在寻找拉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并获取值,那么速度要快两倍以上。

        5
  •  3
  •   fedorqui    11 年前
    map (lambda x:(x[1]),elements)
    
        6
  •  2
  •   Oleg    8 年前

    定时 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() 不再返回列表,因此显式转换。

        7
  •  1
  •   Georgy rassa45    7 年前

    使用 islice chain.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]