【问题标题】:Concatenate elements of a tuple in a list in python在python的列表中连接元组的元素
【发布时间】:2014-01-11 06:44:45
【问题描述】:

我有一个包含字符串的元组列表 例如:

[('this', 'is', 'a', 'foo', 'bar', 'sentences')
('is', 'a', 'foo', 'bar', 'sentences', 'and')
('a', 'foo', 'bar', 'sentences', 'and', 'i')
('foo', 'bar', 'sentences', 'and', 'i', 'want')
('bar', 'sentences', 'and', 'i', 'want', 'to')
('sentences', 'and', 'i', 'want', 'to', 'ngramize')
('and', 'i', 'want', 'to', 'ngramize', 'it')]

现在我希望将每个字符串连接到一个元组中以创建一个空格分隔的字符串列表。 我使用了以下方法:

NewData=[]
for grams in sixgrams:
       NewData.append( (''.join([w+' ' for w in grams])).strip())

它工作得很好。

但是,我拥有的列表有超过一百万个元组。所以我的问题是这种方法是否足够有效,或者是否有更好的方法来做到这一点。 谢谢。

【问题讨论】:

    标签: python string list tuples concatenation


    【解决方案1】:

    你可以像这样高效地做到这一点

    joiner = " ".join
    print map(joiner, sixgrams)
    

    我们仍然可以像这样使用列表理解来提高性能

    joiner = " ".join
    print [joiner(words) for words in sixgrams]
    

    性能比较表明,上面看到的列表理解解决方案比其他两种解决方案略快。

    from timeit import timeit
    
    joiner = " ".join
    
    def mapSolution():
        return map(joiner, sixgrams)
    
    def comprehensionSolution1():
        return ["".join(words) for words in sixgrams]
    
    def comprehensionSolution2():
        return [joiner(words) for words in sixgrams]
    
    print timeit("mapSolution()", "from __main__ import joiner, mapSolution, sixgrams")
    print timeit("comprehensionSolution1()", "from __main__ import sixgrams, comprehensionSolution1, joiner")
    print timeit("comprehensionSolution2()", "from __main__ import sixgrams, comprehensionSolution2, joiner")
    

    在我的机器上输出

    1.5691678524
    1.66710209846
    1.47555398941
    

    性能提升很可能是因为我们不必每次都从空字符串创建连接函数。

    编辑:虽然我们可以像这样提高性能,但最pythonic的方法是使用像lvc's answer这样的生成器。

    【讨论】:

      【解决方案2】:

      列表推导式创建临时字符串。只需改用' '.join

      >>> words_list = [('this', 'is', 'a', 'foo', 'bar', 'sentences'),
      ...               ('is', 'a', 'foo', 'bar', 'sentences', 'and'),
      ...               ('a', 'foo', 'bar', 'sentences', 'and', 'i'),
      ...               ('foo', 'bar', 'sentences', 'and', 'i', 'want'),
      ...               ('bar', 'sentences', 'and', 'i', 'want', 'to'),
      ...               ('sentences', 'and', 'i', 'want', 'to', 'ngramize'),
      ...               ('and', 'i', 'want', 'to', 'ngramize', 'it')]
      >>> new_list = []
      >>> for words in words_list:
      ...     new_list.append(' '.join(words)) # <---------------
      ... 
      >>> new_list
      ['this is a foo bar sentences', 
       'is a foo bar sentences and', 
       'a foo bar sentences and i', 
       'foo bar sentences and i want', 
       'bar sentences and i want to', 
       'sentences and i want to ngramize', 
       'and i want to ngramize it']
      

      以上for循环可以表示为以下列表推导:

      new_list = [' '.join(words) for words in words_list] 
      

      【讨论】:

        【解决方案3】:

        对于大量数据,您应该考虑是否需要将它们全部保存在一个列表中。如果您一次处理每一个,您可以创建一个生成器,该生成器将生成每个连接的字符串,但不会让它们全部占用内存:

        new_data = (' '.join(w) for w in sixgrams)
        

        如果您也可以从生成器中获取原始元组,那么您也可以避免将sixgrams 列表放在内存中。

        【讨论】:

          猜你喜欢
          • 2020-08-08
          • 2016-07-17
          • 1970-01-01
          • 2023-01-12
          • 2014-04-18
          • 1970-01-01
          • 1970-01-01
          • 2011-08-16
          • 2015-12-16
          相关资源
          最近更新 更多