【问题标题】:Find repeated element in a nested list在嵌套列表中查找重复元素
【发布时间】:2019-02-21 12:43:09
【问题描述】:

我有一个嵌套的元素列表:

employee_list =  [
    ['Name', '=', 'John'],
    ['Age', '=', '32'],
    ['Weight', '=', '60'],
    ['Name', '=', 'Steve'],
    ['Weight', '=', '85']
]

我想创建两个元素列表:一个具有重复元素,另一个具有独特元素。但我也希望保持重复

unique_list = [['Age', '=', '32']]

repeated_list = [
    ['Name', '=', 'John'],
    ['Weight', '=', '60'],
    ['Name', '=', 'Steve'],
    ['Weight', '=', '85']
] 

唯一性或重复性由每个子列表的第一个元素决定。例如:'Name''Weight'。如果有两个子列表,其中第一个元素是'Name',我认为它是重复的。

谁能建议一个简单的方法来做到这一点?

【问题讨论】:

  • 你尝试的方法是什么?
  • @benvc 我不认为它是完全重复的,OP 不想删除重复项,他们想对元素进行“分区”。然而,第一个答案已经为一种可能的有效解决方案提供了重要提示。
  • “重复”是指整个子列表['Weight', '=', '60'] 是相同的还是只是其中一个重要元素(如'Weight')?
  • 您要保留原始订单吗?您的列表将包含多少个元素? (我的意思是像 10、100、1000、10 亿?)最重要的是:你试过什么没用?
  • @schwobaseggl 很抱歉,我没有在问题中说清楚。我说的是“姓名”、“体重”或“年龄”等元素的独特性或重复性

标签: python list nested-lists


【解决方案1】:

你不能使用列表列表来做Counter,它会返回

不可散列的类型:'list'

所以我们需要转换为listtuple

employee_tuple=list(map(tuple,employee_list))
# then we using Counter    
from collections import Counter
d=Counter(employee_tuple)

l=list(map(d.get,employee_tuple))# get the freq of each item
l
Out[372]: [2, 1, 2, 2, 2]

# then we using filter 
from itertools import compress
list(compress(employee_list, map(lambda x: x == 1, l)))
Out[380]: [['Age', '=', '32']]


list(compress(employee_list, map(lambda x: x != 1, l)))
Out[384]: 
[['Name', '=', 'John'],
 ['Weight', '=', '60'],
 ['Name', '=', 'John'],
 ['Weight', '=', '60']]

【讨论】:

    【解决方案2】:

    您可以使用collections.Counter 并根据重要的第一个元素的计数来理解这两个列表:

    from collections import Counter
    
    c = Counter(l[0] for l in employee_list)
    # Counter({'Name': 2, 'Weight': 2, 'Age': 1})
    
    uniq = [l for l in employee_list if c[l[0]] == 1]
    # [['Age', '=', '32']]
    
    rept = [l for l in employee_list if c[l[0]] > 1]
    # [['Name', '=', 'John'],
    #  ['Weight', '=', '60'],
    #  ['Name', '=', 'Steve'],
    #  ['Weight', '=', '85']]
    

    更新:rept 拆分为“key”

    d = {}
    for l in rept:
        d.setdefault(l[0], []).append(l)
    list(d.values())
    # [[['Name', '=', 'John'], ['Name', '=', 'John']],
    #  [['Weight', '=', '60'], ['Weight', '=', '60']]]
    

    【讨论】:

    • 感谢您的解决方案。只是出于好奇,如果我想为每组重复元素创建列表。怎么可能达到。例如:rept1 = [['Name', '=', 'John'], ['Name', '=', 'Steve']] 其余部分类似
    • @Deep 我将使用第一个元素作为键和光照列表作为值来构建一个字典。
    • 我的意思是,我们在列表“rept”中得到的输出。它进一步有重复(“名称”和“重量”都是两次)。如果我需要将其分解为仅包含“名称”和“重量”的列表,或者将其分解到其中只有一种元素的列表。
    • @Deep 这正是我的理解。我在答案中添加了一些代码。
    【解决方案3】:

    您可以使用多种解决方案,包括列表解析和过滤器。您还可以使用集合和列表来生成唯一的元素集合并转换回列表,如link provided by benvc 所示 然后在获得唯一元素列表后,您可以从原始列表中过滤这些元素以获得重复的结果列表(如果有的话)

    python tips on filter

    【讨论】:

    • OP 在许多 cmets 澄清了他们真正追求的东西之后编辑了这个问题,这使得我在此处引用的最初建议对解决问题没有帮助。
    【解决方案4】:

    如果您创建了一个包含employee_list 中所有itemstest_list,您可以使用内置的count 方法和count,如果list 中的每个employee_list[i][0] count == 1 然后我们将整个 item 附加到我们的 unique_list

    employee_list =  [
        ['Name', '=', 'John'],
        ['Age', '=', '32'],
        ['Weight', '=', '60'],
        ['Name', '=', 'Steve'],
        ['Weight', '=', '85']
    ]
    
    unique_list = []
    repeated_list = [] 
    test_list = []
    
    for i in employee_list:
        for j in i:
            test_list.append(j)
    
    for i in employee_list:
        if test_list.count(i[0]) == 1:
            unique_list.append(i)
        else:
            repeated_list.append(i)
    
    print(f"Repeated: {repeated_list}")
    print(f"Unique: {unique_list}")
    
    (xenial)vash@localhost:~/python/stack_overflow$ python3.7 unique.py 
    Repeated: [['Name', '=', 'John'], ['Weight', '=', '60'], ['Name', '=', 'Steve'], ['Weight', '=', '85']]
    Unique: [['Age', '=', '32']]
    

    【讨论】:

      【解决方案5】:

      我使用纯 numpy 解决方案(我添加了一行以使其更通用):

      假设这是我们的数据:

      data = np.array(data).astype(str)
      
      data: array([['Name', '=', 'John'],
             ['Age', '_', '32'],
             ['Weight', '=', '60'],
             ['Name', '=', 'John'],
             ['Weight', '=', '60'],
             ['TT', '=', 'EE']], dtype='<U6')
      

      下一步是获取唯一行:

      uniq = np.unique(data, axis=0)
      uniq: array([['Age', '_', '32'],
             ['Name', '=', 'John'],
             ['TT', '=', 'EE'],
             ['Weight', '=', '60']], dtype='<U6')
      

      现在,我们想看看哪些行没有重复多次: (只有一次行的答案:)

      only_once = np.array([row for row in uniq if sum(np.all(row==data, axis=1)) == 1])
      only_once:
      array([['Age', '_', '32'],
             ['TT', '=', 'EE']], dtype='<U6')
      

      为了得到重复的索引:

      idx = []
      for row in only_once:
          lst = np.all(data==row, axis=1)
          idx = np.where(lst)[0]
          idx.append(idx)
      idx:
      [array([1]), array([5])]
      

      唯一重复值的矩阵:

      result = np.delete(data, idx, axis=0)
      result:
      array([['Name', '=', 'John'],
             ['Weight', '=', '60'],
             ['Name', '=', 'John'],
             ['Weight', '=', '60']], dtype='<U6')
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-01-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-31
        • 2010-10-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多