【问题标题】:delete duplicate columns in python list删除python列表中的重复列
【发布时间】:2020-11-21 09:47:36
【问题描述】:

我有以下列表作为示例:

ls=[
    [1, 2, 3, 3, 4, 5, 5, 5, 6],
    ['a', 'a', 'b', 'b', 'c', 'd', 'e', 'f', 'g'],
    ['r', 's' ,'t', 'u', 'v', 'w', 'x', 'y', 'z']
]

我想删除重复的元素,一旦检测到重复,它的索引必须用于删除其他行中具有此索引的所有元素。示例的结果必须是:

[
[1, 3, 4, 5, 6],
['a', 'b', 'c', 'd', 'g'],
['r', 't', 'v', 'w', 'z']
]

我写了以下代码:

#Helping function to delete the elements of col_index from all rows
def delete_col(l, col_index):
    for sl in l:
        del sl[col_index]

#To delete the duplicates.
def list_without_columns_duplicates(l):
    i=0
    j=1
    while i<len(l):
        while j<len(l[0]):
            if l[i][j]==l[i][j-1]:
                delete_col(l, j)
            j+=1
        i+=1

但是,当我运行此代码时,我发现了两个问题:(1) 它只考虑第一行的重复项,以及 (2) 它只删除第一个重复项,并且需要多次运行才能删除所有其他重复项。任何帮助将不胜感激。

【问题讨论】:

  • 您的输入列表长度不同。如果其他列表中缺少索引怎么办?
  • @jizhihaoSAMA,感谢您的回答。但是,使用set(i) 将每一行与其他行分开考虑,因此它不会给出我想要的适当结果
  • @schwobaseggl,我编辑了列表,现在它们的长度相同

标签: python list algorithm


【解决方案1】:

你可以这样做:

from itertools import chain

ls = [
    [1, 2, 3, 3, 4, 5, 5, 5, 6],
    ['a', 'a', 'b', 'b', 'c', 'd', 'e', 'f', 'g'],
    ['r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
]


def find_duplicated_indexes(l):

    seen = set()
    for i, e in enumerate(l):
        if e not in seen:
            seen.add(e)
        else:
            yield i


indexes = set(chain.from_iterable(find_duplicated_indexes(l) for l in ls))
result = [[e for i, e in enumerate(l) if i not in indexes] for l in ls]

print(result)

输出

[[1, 3, 4, 5, 6], ['a', 'b', 'c', 'd', 'g'], ['r', 't', 'v', 'w', 'z']]

【讨论】:

  • 非常感谢。这正是我想要的
【解决方案2】:

您可以获取要避免的索引列表,然后过滤ls的子列表:

from itertools import groupby as gb
ls = [[1, 2, 3, 3, 4, 5, 5, 5, 6], ['a', 'a', 'b', 'b', 'c', 'd', 'e', 'f', 'g'], ['r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']]
inds = {l for j in ls for _, i in gb(list(enumerate(j)), key=lambda x:x[-1]) for l in [a for a, _ in list(i)[1:]]}
r = [[a for i, a in enumerate(b) if i not in inds] for b in ls]

输出:

[[1, 3, 4, 5, 6], ['a', 'b', 'c', 'd', 'g'], ['r', 't', 'v', 'w', 'z']]

【讨论】:

    【解决方案3】:

    如果您可以使用pandas,这是一个更优雅的解决方案:

    import pandas as pd
    
    ls=[
        [1, 2, 3, 3, 4, 5, 5, 5, 6],
        ['a', 'a', 'b', 'b', 'c', 'd', 'e', 'f', 'g'],
        ['r', 's' ,'t', 'u', 'v', 'w', 'x', 'y', 'z']
    ]
    
    df = pd.DataFrame({'id': ls[0], 'A': ls[1], 'B': ls[2]})
    
    print(df.drop_duplicates(subset=['A'], keep='first'))
    
    

    输出:

       id  A  B
    0   1  a  r
    2   3  b  t
    4   4  c  v
    5   5  d  w
    6   5  e  x
    7   5  f  y
    8   6  g  z
    

    【讨论】:

      【解决方案4】:

      这是我开发的一个快速解决方案。

      new_ls = []
      for element in ls:
          inside_list = []
          for el in element:
              if el in inside_list:
                  continue
              inside_list.append(el)
          new_ls.append(inside_list)
      
      ls = new_ls
      

      它所做的只是简单地创建一个新数组并将每个元素附加到嵌套列表中,但如果元素已经在嵌套列表中则跳过一个!

      【讨论】:

        【解决方案5】:

        这可以使用

        set 方法,set 只允许唯一值。

        在您的情况下迭代列表列表,如下所示,然后应用 set 并将其转换为列表。

        new_list 包含您需要的输出。

         new_list = [] 
         for l in ls:
             new_list.append(list(set(l)))
        
         print(new_list)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-07-14
          • 2012-07-11
          • 2011-10-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多