我有以下查询:是否可以按片获取元组中每个字符串的第一个符号元组? 我尝试了以下代码:
t = ("aaa", "aab", "abc", "aba", "bcc")
print(t[:][0])
我得到了“ aaa”。我想要的是['a','a','a','a','b']。 确保可以通过生成器完成:
letters = (x[0] for x in t)
但是可以切成薄片吗? 谢谢。
答案 0 :(得分:2)
以下代码未明确使用切片,但非常有效:
letters = next(zip(*t))
letters
#('a', 'a', 'a', 'a', 'b')
此方法比带选择的列表理解([0]
快25%,比带切片的列表理解([:1]
快48%。
答案 1 :(得分:2)
经典的解决方案是使用列表理解。另一种实用的方法是使用operator.itemgetter
。
但是您可以通过第三方NumPy进一步接近矢量化功能。在这里,您应该看到较大的性能改进。切片是微不足道的;成本主要来自转换为NumPy数组。
NumPy解决方案假定您的字符串长度相同,并且您对将输出作为数组而不是列表感到满意:
res = np.array(t).view('<U1')[::len(t[0])]
一些性能基准测试:
import numpy as np
from operator import itemgetter
t = ("aaa", "aab", "abc", "aba", "bcc")
t = t*500000
t_arr = np.array(t)
def comp(tup):
return [x[0] for x in tup]
def func(tup):
return list(map(itemgetter(0), tup))
def nump(tup):
return np.array(tup).view('<U1')[::len(tup[0])]
def nump2(arr):
return arr.view('<U1')[::len(arr[0])]
def dyz(tup):
letters, *_ = zip(*tup)
return letters
def dyz2(tup):
return next(zip(*tup))
%timeit comp(t) # 276 ms per loop
%timeit func(t) # 338 ms per loop
%timeit nump(t) # 174 ms per loop
%timeit nump2(t_arr) # 2.86 µs per loop
%timeit dyz(t) # 351 ms per loop
%timeit dyz2(t) # 245 ms per loop
答案 2 :(得分:0)
不,这是不可能的,因为Slice不能返回多个String。 您需要在元组上循环:[t中的i的x [0]]。