【问题标题】:Python Combine Repeating ElementsPython 组合重复元素
【发布时间】:2023-04-02 21:48:02
【问题描述】:

我有一个包含一些重复元素的字符串列表,我想将这些元素组合成一个较短的列表。

原始列表内容如下所示:

lst = [['0.1', '0', 'RC', '100'],
        ['0.2', '10', 'RC', '100'],
        ['0.3', '5', 'HC', '20'],
        ['0.4', '5', 'HC', '20'],
        ['0.5', '5', 'HC', '20'],
        ['0.6', '5', 'HC', '20'],
        ['0.7', '5', 'HC', '20'],
        ['0.8', '5', 'HC', '20'],
        ['0.9', '10', 'RC', '100'],
        ['1.0', '0', 'RC', '100']]

通过函数运行后会变成:

lst = [['0.1', '0', 'RC', '100'],
        ['0.2', '10', 'RC', '100'],
        ['0.3', '5', 'HC', '20'],
        ['0.9', '10', 'RC', '100'],
        ['1.0', '0', 'RC', '100']]

列表将始终具有这种一般结构,所以基本上我想根据最后 3 列是否完全相同来组合列表。

我希望它是一个可调用的函数,所以它看起来像这样:

def combine_list(lst):
    if sublist[1:3] == next_sublist[1:3]:
        let.remove(next_sublist)

我对此的初步研究显示了许多基于索引删除子列表的方法,但这不一定事先知道。我还找到了 re 模块,但是我从未使用过它并且不确定如何实现它。提前谢谢你

【问题讨论】:

    标签: python string list sorting


    【解决方案1】:
    for index in range(len(lst) - 1, 0, -1):
        if lst[index][1:] == lst[index - 1][1:]:
            lst.pop(index)
    

    通过向后遍历列表,我们消除了删除元素时索引更改的问题。这会导致就地减少。

    如果您想创建一个新列表,可以按照相同的想法通过列表推导来完成,但是由于我们没有在适当的位置进行操作,因此我们不必逆向工作:

    lst[0] + [lst[ind] for ind in range(1, len(lst)) if lst[ind][1:] != lst[ind-1][1:]]
    

    同样,lst[0] 是非重复的,因此会自动包含在内。

    【讨论】:

      【解决方案2】:
      def combine_list(ls):
          cpy = ls[:]
      
          for i, sub in enumerate(ls[:len(ls) - 1]):
              if sub[1:] == ls[i + 1][1:]:
                  cpy.remove(ls[i + 1])
      
          return cpy
      

      这个功能应该可以工作。它会创建列表的新副本,以避免修改原始列表。然后它遍历原始列表(最后一个值除外),因为它保持不变。

      然后它检查列表的最后一个值是否等于下一个列表的最后一个值。如果是,则删除下一个列表。

      然后该函数返回新列表。

      【讨论】:

        【解决方案3】:

        也许只使用一组来跟踪重复项?

        def combine_list(lst):
            out = []
            seen = set()
            for item in lst:
                if not tuple(item[1:]) in seen:
                    out.append(item)
                    seen.add(tuple(item[1:]))
            return out
        

        列表是一种可变的数据结构。因此不能保证列表的内容不会随着时间而改变。这意味着它不能用于散列函数(集合使用)。另一方面,元组是不可变的,因此是可散列的。

        【讨论】:

        • 不错。你能解释一下为什么你必须转换成tuple吗?
        • 当然。列表是一种可变数据结构。因此不能保证列表的内容不会随着时间而改变。这意味着它不能用于散列函数(集合使用)。另一方面,元组是不可变的,因此是可散列的。
        • 知道 所以我不在乎 :) 没关系,在答案中进行了编辑。 cmets 不是为此而做的。*
        • err,您的答案不会产生预期的结果,因为set 阻止了开始和元素的不同。
        • 哦,对不起,我以为你是 OP。没仔细看。感谢您的编辑。
        【解决方案4】:

        如果您想删除与最后三个元素相同且连续的子列表,则需要在最后三个元素上键入itertools.groupby

        from itertools import groupby
        [next(g) for _, g in groupby(lst, key=lambda x: x[1:])]
        
        #[['0.1', '0', 'RC', '100'],
        # ['0.2', '10', 'RC', '100'],
        # ['0.3', '5', 'HC', '20'],
        # ['0.9', '10', 'RC', '100'],
        # ['1.0', '0', 'RC', '100']]
        

        【讨论】:

        • 我已经用一些我可能遇到的不同情况进行了测试,例如更大的列表和具有多个子组的列表,这在所有情况下都非常有效。谢谢!!!
        • 像这样使用next很棒,因为我们通常使用密钥,但是那里的密钥不完整。
        猜你喜欢
        • 2021-09-10
        • 2015-09-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-18
        • 1970-01-01
        • 2023-02-19
        相关资源
        最近更新 更多