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

问题描述 投票:0回答:5

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

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

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

python list nested-lists
5个回答
5
投票

您可以使用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

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

0
投票

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

不可用的类型:'列表'

所以我们需要转换为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']]

0
投票

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

python tips on filter


0
投票

如果你创建了包含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']]

0
投票

我使用纯粹的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')
© www.soinside.com 2019 - 2024. All rights reserved.