【问题标题】:Joining side by side words from list in Python在 Python 中并排连接列表中的单词
【发布时间】:2019-03-24 14:40:24
【问题描述】:

有一堆从 .txt 文件转换而来的列表,这些列表已被读取为字符串集合,如下所示:

['New', 'Jersey', '1', '0', '1', '999']
['West', 'North', 'Central', '1', '0', '100', '90']

这些列表有不同数量的并排单词(第一个有 2 个,第二个有 3 个,等等)

我想输出一个新列表(然后进入编译的数据框),它将并排的单词连接在一起,例如:

['New Jersey', '1', '0', '1', '999']
['West North Central', '1', '0', '100', '90']

这将使新列表(和数据框)的长度相同。

append(line.split()) 放入每个字符串的新列表很容易,但无法弄清楚连接所有单词并分别附加每个数字所需的 if 语句和 .join()。

【问题讨论】:

    标签: python string python-3.x list dataframe


    【解决方案1】:
    line = ['West', 'North', 'Central', '1', '0', '100', '90']
    words = []
    nums = []
    
    for word in line:
        if word.isalpha():
            words.append(word)
        else:
            nums.append(word)
    
    new_line = [' '.join(words)]
    new_line.extend(nums)
    
    # new_line == ['West North Central', '1', '0', '100', '90']
    

    【讨论】:

    • if word.isalpha(): 可以替换all(...),也可以在循环中追加/扩展到new_line
    【解决方案2】:

    使用itertools.groupby,可以按str.isalpha分组,有条件地连接字符串,然后链接结果:

    from itertools import chain, groupby
    
    L = ['New', 'Jersey', '1', '0', '1', '999']
    
    grouper = groupby(L, key=str.isalpha)
    joins = [[' '.join(v)] if alpha_flag else list(v) for alpha_flag, v in grouper]
    res = list(chain.from_iterable(joins))
    
    print(res)
    
    ['New Jersey', '1', '0', '1', '999']
    

    【讨论】:

    • @pault,哇,相隔 4 秒!
    • 我也有同样的想法!也就是说,我不确定这些带有嵌套和扁平化的构造是否比带有附加和扩展的常规 for 循环更好
    • @blhsing 'kids' > 'SO' 幸运的是 True ;)
    • @blhsing(将评论从您的回答移至此处) - 尽管在这个特定示例中不会有太大影响,但使用 list.__add__ 通常是 bad way of flattening nested lists
    • @blhsing 我很惊讶你和 jpp 在这个上进行了 groupby,也许我失去了伟大的思想联系:/
    【解决方案3】:

    您可以编写自己的函数来进行连接,例如:

    l = [
        ['New', 'Jersey', '1', '0', '1', '999'],
        ['West', 'North', 'Central', '1', '0', '100', '90']]
    
    def my_concat(l):
        nl = []
        cur = None
        delim = ""
        for i in l:
            if isinstance(i, (str, unicode)) and i.isalpha():
                if cur == None:
                    cur = ""
                cur += delim + i
                delim = " "
            else:
                if cur != None:
                    nl.append(cur)
                    cur = None
                    delim = ""
                nl.append(i)
        return nl
    
    for i in l:
        print my_concat(i)
    

    输出:

    ['New Jersey', '1', '0', '1', '999']
    ['West North Central', '1', '0', '100', '90']
    

    【讨论】:

      【解决方案4】:

      你可以使用itertools.groupby:

      from itertools import groupby
      l = [
          ['New', 'Jersey', '1', '0', '1', '999'],
          ['West', 'North', 'Central', '1', '0', '100', '90']
      ]
      print([list.__add__(*(list(g) if k else [' '.join(g)] for k, g in groupby(s, key=str.isdigit))) for s in l])
      

      这个输出:

      [['New Jersey', '1', '0', '1', '999'], ['West North Central', '1', '0', '100', '90']]
      

      【讨论】:

        【解决方案5】:

        我基本上是在遍历 list1 中的字符串。如果它恰好是一个单词,我将它附加到 list2,否则它会附加到 list3。如果字符串仅包含数字,则 isdigit() 方法返回 true。最后使用'join'将list2的所有内容添加为单个字符串,并使用extend将list3的所有元素添加到answer[]的末尾。

        list1=['West North Central', '1', '0', '100', '90']
        list2=[]
        list3=[]
        for i in list1:
            if i.isdigit():
                list3.append(i)
            else:
                list2.append(i)
        answer = []
        answer.append(' '.join(list2))
        answer.extend(list3)
        

        【讨论】:

        • 能否请您为您的代码添加更多解释。谢谢。
        • 不确定哪部分代码不清楚,能否指出哪部分需要解释
        • 我知道这对专业人士来说是很清楚的,但第一步是了解人们需要对每一行进行更多解释,只是暗示你编写这行代码的原因。谢谢。再次欢迎来到堆栈溢出的世界来解释代码。
        • @hollopost 我已经编辑了答案,如果现在清楚,请告诉我。谢谢
        • 感谢您的快速响应。我希望我不是讨厌的人。但为了清楚起见,这是堆栈溢出的角色。现在很清楚了,谢谢。
        【解决方案6】:

        我建议以下步骤:

        1) 查找单词主菜的索引 2)如果您有两个或多个连续的非数字索引,请附加它们

        案例:

        import re
        
        numeric_regex = re.compile('[0-9]+?') #Regex to find numeric indices 
        test = ['New', 'Jersey', '1', '0', '1', '999', 'West', 'North', 'Central', '1', '0']
        
        #Comprehension to find word indices 
        word_indices = [idx for idx, x in enumerate(test) if numeric_regex.match(x) is None]
        
        #Comprehension to find indices to merge on
        merge_on = [idx for idx, x in enumerate(word_indices) if word_indices[idx-1] == x-1]
        

        在这一点上,我很难在没有 for 循环的情况下做到这一点,所以我将只使用 for 循环:

        reversed_merge_on = reversed(merge_on)
        for x in reversed_merge_on:
            test[word_indices[x]-1] = ' '.join(test[word_indices[x]-1:word_indices[x]+1])
            del test[word_indices[x]]
        

        这将使您通过任何给定的列表。您可以将其放入一个函数并将其应用于许多列表。上面的代码将按原样运行,因此您可以复制到 Python(我使用的是 2.7)自己查看。

        【讨论】:

          【解决方案7】:

          使用列表推导并将非数字项连接到一个索引中,然后为数字解包列表推导。

          lst = ['West', 'North', 'Central', '1', '0', '100', '90']
          res = [' '.join([i for i in lst if not i.isdigit()]),*[i for i in lst if i.isdigit()]]
          print(res)
          # ['West North Central', '1', '0', '100', '90']
          

          【讨论】:

          • 如果列表类似于lst = ['1', '0', '100', '90', 'West', 'North', 'Central']
          • @KhalilAlHooti 那么它仍然有效,您是否尝试将其插入?
          • 它返回['West North Central', '1', '0', '100', '90'],而不是['1', '0', '100', '90', 'West North Central']
          • @KhalilAlHooti 不是想要的输出,为什么我们会产生与想要的输出相反的输出,所有演示的输出都是首先组织的,没有提到它应该是其他的
          • @KhalilAlHooti 我尊重并理解你的意思,但我必须根据 OP 提供的内容来调整我的回复,并且唯一提供的东西是这种方式的输出,假设也是有原因的
          猜你喜欢
          • 1970-01-01
          • 2021-01-11
          • 1970-01-01
          • 1970-01-01
          • 2020-04-19
          • 1970-01-01
          • 1970-01-01
          • 2019-05-12
          • 1970-01-01
          相关资源
          最近更新 更多