【问题标题】:python map string split listpython映射字符串拆分列表
【发布时间】:2012-01-17 16:11:21
【问题描述】:

我正在尝试将str.split 函数映射到字符串数组。即,我想将所有字符串拆分为遵循相同格式的字符串数组。知道如何在 python 中使用map 做到这一点吗?例如,假设我们有一个这样的列表:

>>> a = ['2011-12-22 46:31:11','2011-12-20 20:19:17', '2011-12-20 01:09:21']

想要使用 map 将字符串按空格 (split(" ")) 拆分以得到一个列表:

>>> [['2011-12-22', '46:31:11'], ['2011-12-20', '20:19:17'], ['2011-12-20', '01:09:21']]

【问题讨论】:

    标签: python string parsing functional-programming


    【解决方案1】:

    这就是我的做法:

    >>> a=['2011-12-22 46:31:11','2011-12-20 20:19:17', '2011-12-20 01:09:21']
    >>> map(str.split, a)
    [['2011-12-22', '46:31:11'], ['2011-12-20', '20:19:17'], ['2011-12-20', '01:09:21']]
    

    只有当你知道你有一个str 的列表时才有效(即不仅仅是一个以与str 兼容的方式实现split 方法的事物的列表)。它还依赖于使用split() 的默认行为,它在任何空格上分割,而不是使用x.split(' '),它只在空格字符上分割(即不是制表符、换行符或其他空格),因为你不能通过使用此方法的另一个参数。对于比这更复杂的调用行为,我会使用列表推导。

    【讨论】:

    • 如何给像“\t”和“1”这样的分割参数
    • @Vignesh “对于比这更复杂的调用行为,我会使用列表理解”。您在列表上映射的东西必须可以用一个参数调用。您始终可以将 split 方法调用包装在一个新函数中(可能使用 lambda 内联定义),以便制作可以使用一个参数调用并且还将传递附加分隔符参数的东西。但它的可读性通常不如[x.split('\t') for x in a],除非它是你已经定义和命名的东西。
    【解决方案2】:

    社区 wiki 答案以比较给出的其他答案

    >>> from timeit import Timer
    >>> t = {}
    >>> t['methodcaller'] = Timer("map(methodcaller('split', ' '), a)", "from operator import methodcaller; a=['2011-12-22 46:31:11','2011-12-20 20:19:17', '2011-12-20 01:09:21']")
    >>> t['lambda'] = Timer("map(lambda s: s.split(), a)", "a = ['2011-12-22 46:31:11','2011-12-20 20:19:17', '2011-12-20 01:09:21']")
    >>> t['listcomp'] = Timer("[s.split() for s in a]", "a = ['2011-12-22 46:31:11','2011-12-20 20:19:17', '2011-12-20 01:09:21']")
    >>> for name, timer in t.items():
    ...     print '%s: %.2f usec/pass' % (name, 1000000 * timer.timeit(number=100000)/100000)
    ... 
    listcomp: 2.08 usec/pass
    methodcaller: 2.87 usec/pass
    lambda: 3.10 usec/pass
    

    【讨论】:

    • 有趣的是他们是如何按照速度排序的。
    【解决方案3】:

    虽然不为人所知,但有一个专门为此目的设计的函数,operator.methodcaller

    >>> from operator import methodcaller
    >>> a = ['2011-12-22 46:31:11','2011-12-20 20:19:17', '2011-12-20 01:09:21']
    >>> map(methodcaller("split", " "), a)
    [['2011-12-22', '46:31:11'], ['2011-12-20', '20:19:17'], ['2011-12-20', '01:09:21']]
    

    这种技术比使用 lambda 表达式的等效方法更快。

    【讨论】:

    • 这绝对是最好的答案,因为它允许我将 str.split 关键字参数 sep=" " 传递给 str.split 函数。我不确定如何才能做到这一点,因为map(str.split('\t'), a) 不起作用。谢谢!
    【解决方案4】:

    map(lambda x: x.split(), a) 但是,在这种情况下,使用列表理解 [x.split() for x in a] 会更清晰。

    【讨论】:

    • 尽管 OP 明确要求 map,但这个答案表明使用列表理解更简洁、更 Pythonic。
    • @kojiro 这是非常主观的。来自函数式编程背景,地图比列表理解更容易阅读/更清晰(对我而言)。
    【解决方案5】:

    map 与函数结合使用。一个简洁的方法是使用lambda 函数:

    >>> a=['2011-12-22 46:31:11','2011-12-20 20:19:17', '2011-12-20 01:09:21']
    >>> map(lambda s: s.split(), a)
    [['2011-12-22', '46:31:11'], ['2011-12-20', '20:19:17'],
     ['2011-12-20', '01:09:21']]
    

    【讨论】:

    • 您可以使用map(str.split, a)进行简化
    猜你喜欢
    • 2013-12-15
    • 1970-01-01
    • 2011-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多