没有循环的元组的元组索引列表

时间:2018-08-11 20:24:04

标签: python

list1 = [((100,3),3,5,6),((200,3),3,5,6),((300,3),3,5,6),((400,3),3,5,6)]

我想从列表中获取每个元组的第一个元素。

我可以使用循环轻松实现它:

for i in list1:
  print(i[0][0])

但是可以避免for循环吗?

5 个答案:

答案 0 :(得分:2)

列表理解,实际上与循环相同。

[i[0][0] for i in list1]

或者,您可以使用熊猫。

import pandas as pd

pd.Series(list1).str[0].str[0]

答案 1 :(得分:1)

您可以使用numpy,并且使用的唯一循环是隐式且快速的。但也不太可读:

import numpy as np

>>> np.stack(np.array(list1)[:,0])[:,0]

array([100, 200, 300, 400])

答案 2 :(得分:0)

在此处对所有建议的方法运行%% timeit,这比除一个建议以外的大多数建议都快

用numpy给出:

  

每个循环31.6 µs±1.13 µs(平均±标准偏差,共运行7次,每个10000个循环)

它给了熊猫:

  

每个循环475 µs±20.5 µs(平均±标准偏差,共运行7次,每个循环1000个)

使用正则表达式的结果是:

  

每个循环8.67 µs±50.1 ns(平均±标准偏差,共运行7次,每个循环100000次)

具有列表比较:

  

每循环837 ns±8.81 ns(平均±标准偏差,共运行7次,每个循环1000000次)

一种非常不同且更快的方法可以是:

list1 = [((100,3),3,5,6),((200,3),3,5,6),((300,3),3,5,6),((400,3),3,5,6)]

list1=str(list1)
import re
d=re.findall("(?:\(\()(\d+)",list1)
[int(x) for x in d]

输出

[100, 200, 300, 400]

答案 3 :(得分:0)

您可能需要列表理解。但作为参考,您可以将next与迭代器结合使用,或将operator.itemgetter用于功能性解决方案:

from operator import itemgetter

def first_lazy(x): return map(itemgetter(0), x)
def first(x): return next(zip(*x))

%timeit [i[0][0] for i in list1]             # 44.9 ms
%timeit list(first_lazy(first_lazy(list1)))  # 68.6 ms
%timeit first(first(list1))                  # 78.9 ms

答案 4 :(得分:0)

享受next(zip(*next(zip(*list1)))) :)

P.S .:这是一些解释。

首先,我假设您正在使用Python 3,因此zip返回一个生成器对象,因此对next的后续调用是有效的。因此,为了将list1中每个元组的第一项(即2元素元组)分组在一起,我们使用next(zip(*list1))。在Python 2中,您可以执行zip(*list1)[0]甚至next(iter(zip(*list1))),因为zip返回一个列表。请注意,zip需要多个可迭代对象作为输入,因此我们使用*list1的每个条目(即5元素元组)作为单独的参数传递给{{1} },因此基本上zip的含义与

相同
zip(*list1)

无论如何,在Python 3和Python 2中,第一步之后的输出如下:

zip( ((100,3),3,5,6), ((200,3),3,5,6), ((300,3),3,5,6), ((400,3),3,5,6) )

因此,现在我们必须将结果序列中每个元组的第一个条目分组在一起。听起来很熟悉,不是吗?确实,我们已经在第一步中做到了!因此,再次应用((100, 3), (200, 3), (300, 3), (400, 3)) 之后,我们将获得最终答案:

next(zip(*))