【问题标题】:Python: get first elements from tuple of stringsPython:从字符串元组中获取第一个元素
【发布时间】:2018-12-31 06:29:00
【问题描述】:

我有以下查询:是否可以按切片获取元组中每个字符串的第一个符号元组? 我试过以下代码:

t = ("aaa", "aab", "abc", "aba", "bcc")
print(t[:][0])

我得到了“aaa”。我想要的是['a','a','a','a','b']。 当然可以通过生成器完成:

letters = (x[0] for x in t)

但是可以切片吗? 谢谢。

【问题讨论】:

  • 你应该使用列表理解:letters = [x[0] for x in t].
  • 我不明白你怎么能单独使用切片来做到这一点......但如果可能的话我会很感兴趣......
  • 找不到更好的切片:[x[0:1] for x in t].
  • @Austin [x[:1] for x in t] 更好。
  • 性能方面,[:1] 比 [0:1] 快 10%。

标签: python string list tuples slice


【解决方案1】:

经典的解决方案是使用列表推导。另一种功能性方法是使用operator.itemgetter。

但是您可以通过第 3 方 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】:

    以下代码没有显式使用切片,但是效率很高:

    letters = next(zip(*t))
    letters
    #('a', 'a', 'a', 'a', 'b')
    

    此方法比带有选择的列表解析 ([0]) 快 25%,比带有切片的列表解析 ([:1]) 快 48%。

    【讨论】:

      【解决方案3】:

      不,这是不可能的,因为一个 Slice 不能返回多个字符串。 你需要循环你的元组:[x[0] for i in t]。

      【讨论】:

        猜你喜欢
        • 2021-04-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-21
        • 1970-01-01
        • 1970-01-01
        • 2019-03-26
        相关资源
        最近更新 更多