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循环吗?
答案 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(*))