问题描述
我有一个嵌套的元素列表:
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'
我认为它是重复的。
谁能建议一个简单的方法来做到这一点?
1楼
您可以使用并根据重要的第一个元素的计数来理解两个列表:
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']]]
2楼
您不能使用列表列表做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']]
3楼
您可以使用多种解决方案,包括列表推导和过滤器。 您还可以使用集合和列表来生成唯一的元素集,然后转换回列表,如的所示。然后,在获得唯一元素的列表之后,您可以从原始列表中过滤那些元素以得到结果重复清单(如果有)
查看
4楼
如果你创建了一个test_list
包含所有的items
在employee_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']]
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')