我有一本字典,每个键都有一个元组列表。列表的长度各不相同,但每个元组有4个条目。下面是一个关键的例子
genes = {'Tcea1': [
('995', '057', '551', '613'),
('825', '912', '541', '683'),
('541', '683', '821', '877'),
('825', '912', '538', '683'),
('538', '683', '821', '877'),
('489', '584', '551', '613')]}
我想要做的是删除重复项。但我关心的唯一部分是指数位置1和2.所以在上面的例子中我想要('541','683','821','877')和('538','683',' 821','877')被删除,因为索引1对于两者都是683而索引2对于两者都是821。理想情况下,输出将是
genes = {'Tcea1': [
('995', '057', '551', '613'),
('825', '912', '541', '683'),
('825', '912', '538', '683'),
('489', '584', '551', '613')]}
这让我很难过。以下是我能得到的最接近的。以下代码将删除其中一个元组,但我希望两个都消失了
seen = set()
seen_add = seen.add
genes['Tcea1'] = [x for x in genes['Tcea1'] if tuple(x[1:3]) not in seen and not seen_add(tuple(x[1:3]))]
编辑:我需要保留订单
答案 0 :(得分:4)
您可以执行以下操作:
from collections import Counter
def selectUnique(x):
count = Counter((i[1], i[2]) for i in x)
out = [i for i in x if count[(i[1], i[2])] == 1]
return out
计数器只是一个将键映射到频率的字典。
答案 1 :(得分:1)
您可以使用Counter
检测重复项,然后根据它进行过滤:
from collections import Counter
def myfilter(list_of_tuples):
key = lambda tpl: tpl[1:3]
counter = Counter(key(t) for t in list_of_tuples)
return [ t for t in list_of_tuples if counter[key(t)] <= 1 ]
并适用于你的dict:
new_genes = { k: myfilter(v) for k,v in genes.items() }
此解决方案也保留了订单。
答案 2 :(得分:1)
最短的解决方案是
{ k: [ a for a in genes[k] if len([ b for b in genes[k] if b[1:3] == a[1:3] ]) < 2 ] for k in genes }
如果列表相对较短应该是好的。
答案 3 :(得分:0)
在我看来,这是最简单的方式
>>> from collections import Counter
>>> counter = Counter(x[1:3] for x in genes['Tcea1'])
>>> filter(lambda x: counter[x[1:3]] == 1, genes['Tcea1'])
[('995', '057', '551', '613'), ('825', '912', '541', '683'), ('825', '912', '538', '683'), ('489', '584', '551', '613')]