如何查找重复的列表值?

时间:2019-08-25 22:49:59

标签: python list loops dictionary

我有一个不寻常的任务。数据:

[(1566767777.0, 'Aaron Paul', 'dorety1', 'sfp_names', 'HUMAN_NAME', 100, 100, 0, '8ff7', '08f3', 'Human Name', 'ENTITY', '19fd', 0, 0),
 (1566767863.0, 'Aaron Paul', "{'username': 'aaronpaul', 'last_name': 'Paul', 'friends_count': 509, 'is_group': False, 'is_active': True, 'trust_request': None, 'phone': None, 'profile_picture_url': 'http, 'is_blocked': False, 'id': '1690', 'identity': None, 'date_joined': '2015-05-22T18:58:12', 'about': ' ', 'display_name': 'Aaron Paul', 'first_name': 'Aaron', 'friend_status': None, 'email': None}", 'sfp_names', 'HUMAN_NAME', 100, 100, 0, '7049', 'a458', 'Human Name', 'ENTITY', '19fd', 0, 0),
 (1566, 'Aaron Paul', 'Possible full name: Aaron Paul', 'sfp_names', 'HUMAN_NAME', 100, 100, 0, '6685', '235f', 'Human Name', 'ENTITY', '19fd', 0, 0),
 (1566767503.0, 'Antoine Griezmann', 'dorety', 'sfp_names', 'HUMAN_NAME', 100, 100, 0, '16ab', '08f3', 'Human Name', 'ENTITY', '19fd', 0, 0),
 (1566767108.0, 'Boris Johnson', 'dorety', 'sfp_names', 'HUMAN_NAME', 100, 100, 0, '7931', '08f3', 'Human Name', 'ENTITY', '19fd', 0, 0)]

我需要从其中[1]被重复而[3]不被重复​​的turple中获取值。也就是说,在上面的数据中,我们始终具有相同的[3](sfp_names),在[1](A​​aron Paul)的多个结果中,也就是说,从该列表中我们应该只得到(1566767777.0, 'Aaron Paul', 'dorety1' , 'sfp_names', 'HUMAN_NAME', 100, 100, 0, '8ff7', '08f3', 'Human Name', 'ENTITY', '19fd', 0, 0)和另外两个名为Aaron Paul的名称。由于通常出现的列表数量没有区别,我们需要从这三个列表[['Aaron Paul', 'sfp_names']]中获得相同的值,但是如果我们使用模块名称的第三个turple sfp_names_2,那么我们需要获取两个值,因为模块不同。[['Aaron Paul', 'sfp_names'], ['Aaron Paul', 'sfp_names_2']]

关于我自己所做的事情,这部分我什么都没想到。我只是有办法在列表中查找重复项。

我了解我所描述的内容很难理解,因此我举了一些简单的示例说明其在下面的工作方式

简单版本

数据:

[(0, 'Boby', 'beekeeper'), (1, 'Boby', 'beekeeper'), (2, 'Boby', 'beekeeper'), (3, 'Boby', 'gardener')]

结果:

['Boby', 'beekeeper']

数据:

[(0, 'Boby', 'beekeeper'), (1, 'Boby', 'beekeeper'), (2, 'Boby', 'beekeeper'), (3, 'Boby', 'gardener'), (4, 'Boby', 'gardener'), (5, 'Jack', 'gardener')]

结果:

[['Boby', 'beekeeper'], ['Boby', 'gardener']]

2 个答案:

答案 0 :(得分:1)

如果我正确理解了您的问题,那么您正在寻找从元组列表中获取所有元组,这些元组对于元组的特定元素具有重复的值,但只希望保留那些具有不同值的重复组元组的其他某些特定元素的值?

如果是这样,我很遗憾地说您没有很好地解释这一点,而我提到的是,因为您对问题有一个清晰的了解,因此您可以用几句话来解释它,是编写某些东西的最好的第一步。

示例数据:

[('a', 1, 0), ('a', 2, 0), ('b', 1, 0), ('c', 1, 0), ('c', 1, 0)]

在此示例中,假设您要查看第1个(索引0)和第2个(索引1)元素,那么我希望您希望使用[('a', 1, 0), ('a', 2, 0)]作为结果。不包含带有'b'的元组,因为没有秒数;不包括带有'c'的元组,因为没有秒数,但是其他元素没有不同的值。 / p>

第二个例子

('d', 1, 0), ('d', 2, 0), ('d', 2, 1)]

此处显示您未解决的内容。应该包括它们,因为第一个元素对于所有元素都是相同的,而第二个元素不是相同的,但是应该包括所有三个元素,或者只包含其中一个2的元组中的一个(随机或第一个)。第二要素?我假设您想要所有这些,因为它们符合您的前两个条件。

from itertools import groupby

data = [('a', 1, 0), ('a', 2, 0), ('b', 1, 0), ('c', 1, 0), ('c', 1, 0)]


def my_filter(el1, el2, xs):
    return [e for l in [list(g) for k, g in groupby(xs, lambda x: x[el1])]
            for e in l if len(set([e[el2] for e in l])) > 1]


print(my_filter(0, 1, data))

答案 1 :(得分:1)

我不确定我是否正确理解您的语言:

您想获取列表中具有多次出现的条目集合的列表的所有元素(元组)吗?!

如果将itertools.groupbyoperator.itemgetter结合使用,则可以实现紧凑的实现。 这实际上导致单线表达

from operator import itemgetter
from itertools import groupby

# how often must the pattern appear (redundancy)
# what indices determine the pattern (target_slots)
redundancy, target_slots = 2, (1, 2)

eg_data_2 =  [(0, 'Boby', 'beekeeper'), (1, 'Boby', 'beekeeper'), (2, 'Boby','beekeeper'), (3, 'Boby', 'gardener'), (4, 'Boby', 'gardener'), (5, 'Jack', 'gardener')]

targets = [k for k, v in groupby(eg_data_2, itemgetter(*target_slots)) if sum(1 for _ in v)>=redundancy]

targets
Out[6]: [('Boby', 'beekeeper'), ('Boby', 'gardener')]

对于原始数据(下面的orig_data),您将获得:

target_slots = [1,3]
targets = [k for k, v in groupby(orig_data, itemgetter(*target_slots)) if sum(1 for _ in v)>=redundancy]

In [9]: targets                                                           
Out[9]: [('Aaron Paul', 'sfp_names')]


或者,您可以单独使用itemetter运算符。想法是将元素集合用作键,其值是该特定集合的元素索引列表然后,如果此列表的长度大于您选择的阈值(下面的redundancy参数),我们将报告此特定集合:

from operator import itemgetter
from collections import defaultdict

# how many times must the collection of elements appear
redundancy = 2
# what are the indices of the collection
target_slots = [1, 2] 

# the example data:
eg_data_2 =  [(0, 'Boby', 'beekeeper'), (1, 'Boby', 'beekeeper'), (2, 'Boby','beekeeper'), (3, 'Boby', 'gardener'), (4, 'Boby', 'gardener'), (5, 'Jack', 'gardener')]


occurences = defaultdict(list)  # this is just convenient, you can use a normal dict as well.
for i, entry in enumerate(eg_data_2):
    occurences[itemgetter(*target_slots)(entry)].append(i)
targets = [k for k,v in occurences.items() if len(v) >=redundancy]
targets
Out[18]: [('Boby', 'beekeeper'), ('Boby', 'gardener')]

如果您想要元素而不是重复的条目,则需要稍微修改targets的语句,因为sum(1...已经消耗了组迭代器。

这是它的外观:

from operator import itemgetter
from itertools import groupby

redundancy, target_slots = 2, (1, 2)

eg_data_2 =  [(0, 'Boby', 'beekeeper'), (1, 'Boby', 'beekeeper'), (2, 'Boby','beekeeper'), (3, 'Boby', 'gardener'), (4, 'Boby', 'gardener'), (5, 'Jack', 'gardener')]

_targets = [(k, [e for e in v]) for k, v in groupby(eg_data_2, itemgetter(*target_slots))]
targets = [tg[1] for tg in _targets if len(tg[1]) >= redundancy]

哪个会给:

[ins] In [6]: targets                                                           
Out[6]: 
[[(0, 'Boby', 'beekeeper'),
  (1, 'Boby', 'beekeeper'),
  (2, 'Boby', 'beekeeper')],
 [(3, 'Boby', 'gardener'), (4, 'Boby', 'gardener')]]