当前位置: 代码迷 >> python >> 在嵌套列表中查找重复的元素
  详细解决方案

在嵌套列表中查找重复的元素

热度:15   发布时间:2023-07-14 08:59:04.0

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

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'我认为它是重复的。

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

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

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通过“钥匙”

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

您不能使用列表列表做Counter ,它将返回

不可散列的类型:“列表”

所以我们需要转换为tuple list

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']]

您可以使用多种解决方案,包括列表推导和过滤器。 您还可以使用集合和列表来生成唯一的元素集,然后转换回列表,如的所示。然后,在获得唯一元素的列表之后,您可以从原始列表中过滤那些元素以得到结果重复清单(如果有)

查看

如果你创建了一个test_list包含所有的itemsemployee_list您可以使用内置的count方法和count每个出场employee_list[i][0]list ,如果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']] 

我使用纯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')
  相关解决方案