python中编写程序删除列表中的重复值_从Python中删除字典中项目的重复值

如何检查和删除字典中项目的重复值?

我有一个大型数据集,所以我正在寻找一种有效的方法。 以下是包含副本的字典中的值的示例:

1'word': [('769817', [6]), ('769819', [4, 10]), ('769819', [4, 10])]

需要成为

1'word': [('769817', [6]), ('769819', [4, 10])]

你的问题中没有python字典,只有整数和字符串,列表和元组。 你是什么意思"字典"?

示例是字典中的项目的值,我必须显示它包含的内容

这是stackoverflow.com/questions/2931672/的副本

再次,我不是只使用列表!

这个问题基本上归结为从不可用类型列表中删除重复项,为此无法转换为集合。

一种可能的方法是在构建新列表值时检查当前值的成员资格。

1

2

3

4

5

6

7d = {'word': [('769817', [6]), ('769819', [4, 10]), ('769819', [4, 10])]}

for k, v in d.items():

new_list = []

for item in v:

if item not in new_list:

new_list.append(item)

d[k] = new_list

或者,使用groupby()获得更简洁的答案,尽管可能更慢(列表必须先排序,如果是,那么它比进行成员资格检查更快)。

1

2

3

4

5

6import itertools

d = {'word': [('769817', [6]), ('769819', [4, 10]), ('769819', [4, 10])]}

for k, v in d.items():

v.sort()

d[k] = [item for item, _ in itertools.groupby(v)]

输出 - > {'word': [('769817', [6]), ('769819', [4, 10])]}

谢谢你的作品!

添加了另一种方法,我将探索两种方法的基准标记,以查看哪些方法可以更好地使用您的数据集。

@mrdomoboto:为什么list()包装genexpr?无论如何,[item for item, _ in itertools.groupby(v)]将比传递给list构造函数的genexpr更快/更简洁。此外,如果list未排序,groupby只会慢一些;如果它已经排序,如在例子中,不需要排序,所以它实际上比理论上的任何其他解决方案更快(O(n)没有有意义的常数因子)。如果需要通过将理解改为list(map(operator.itemgetter(0), itertools.groupby(v)))(list()包装仅为Py3)将所有工作推送到C层,它可以进一步优化。

你是对的,list()包装器确实为该行增加了另一个数量级的成本。我更新了我的答案。是的,如果列表已经排序,groupby()会快得多,这就是我添加注释的原因。

那个怎么样?

1

2

3

4

5

6

7

8def remove_duplicates(d: dict):

unique_values = set(d.values())

o = {}

for k, v in d.items():

if v in unique_values:

o[k] = v

unique_values.remove(v)

return o

您可以根据它们生成的哈希来对项目进行统一。哈希可以是任何东西,排序json.dumps或cPickle.dumps。

这个班轮可以根据需要统一你的词典。

1

2

3

4>>> d = {'word': [('769817', [6]), ('769819', [4, 10]), ('769819', [4, 10])]}

>>> import json

>>> { k: { json.dumps(x,sort_keys = True):x for x in v}.values() for k,v in d.iteritems()}

{'word': [('769817', [6]), ('769819', [4, 10])]}

这个怎么样:

我只关注列表部分:

1

2

3

4>>> s = [('769817', [6]), ('769819', [4, 10]), ('769819', [4, 10])]

>>> [(x,y) for x,y in {key: value for (key, value) in s}.items()]

[('769817', [6]), ('769819', [4, 10])]

>>>

该列表理解可简化为:dict(s).items()(Py3上的list(dict(s).items()))。当数据已经是构造函数所期望的数据时,无需将所有内容都变成理解。它也只能通过tuple中的第一个元素而不是第二个元素进行统一,并且不保留顺序,这可能与要求不匹配。如果这是可以接受的,它的效率。

这非常周到,效率更高。

Strikethrough在编辑之前应用于原始问题,留给子孙后代:

你根本不使用dict,只是list的两个tuple,其中每个tuple中的第二个元素本身是list。如果你真的想要dict,

1dict([('769817', [6]), ('769819', [4, 10]), ('769819', [4, 10])])

将它转换,并通过键进行统一(因此你最终会得到{'769817': [6], '769819': [4, 10]},虽然它会失去秩序,并且不会注意值(sub list s)是否唯一(it)只保留给定密钥的最后一个配对。 s>

如果你需要在保留顺序的同时统一相邻的重复项(值对唯一性很重要),并且不需要/需要真正的dict,请使用itertools.groupby:

1

2

3

4

5

6

7import itertools

nonuniq = [('769817', [6]), ('769819', [4, 10]), ('769819', [4, 10])]

uniq = [k for k, g in itertools.groupby(nonuniq)]

# uniq is [('769817', [6]), ('769819', [4, 10])]

# but it wouldn't work if the input was

# [('769819', [4, 10]), ('769817', [6]), ('769819', [4, 10])]

# because the duplicates aren't adjacent

如果您需要折叠不相邻的重复项,并且不需要保留顺序(或排序顺序很好),您可以使用groupby来获取O(n log n)解决方案(而不是创建新列表的天真解决方案)并通过检查O(n^2)复杂度的新列表中的存在,或基于set的解决方案O(n)但要求您将数据中的sub list转换为tuple来避免重复他们可以洗):

1

2

3# Only difference is sorting nonuniq before grouping

uniq = [k for k, g in itertools.groupby(sorted(nonuniq))]

# uniq is [('769817', [6]), ('769819', [4, 10])]

我正在使用字典。我有1个键的多个元组

@Brutalized:你原来的问题没有说清楚。在任何情况下,最后两个选项是当前接受的答案的更优化版本(如果数据已经订购,非排序groupby是O(n),如果需要排序,则其O(n log n),两者都是是对list循环的一个重大改进,list包含每次迭代的检查。

你有一个列表,而不是字典。 Python字典可能只有每个键的一个值。尝试

1my_dict = dict([('769817', [6]), ('769819', [4, 10]), ('769819', [4, 10])])

结果:

1{'769817': [6], '769819': [4, 10]}

一本Python字典。有关更多信息,请访问https://docs.python.org/3/tutorial/datastructures.html#dictionaries

这不会返回列表。

我确实有多个项目作为价值

1

2

3

4

5

6

7your_list = [('769817', [6]), ('769819', [4, 10]), ('769819', [4, 10])]

new = []

for x in your_list:

if x not in new: new.append(x)

print(new)

>>>[('769817', [6]), ('769819', [4, 10])]

这是对列表理解的可怕滥用。不要使用list理解副作用。它们是一个功能构造,功能代码是无副作用的;使用它们来产生副作用是浪费的(造成list的垃圾list,之后被扔掉)并且令人困惑。只需对这些情况使用普通的for循环。另外,永远不要命名变量list;阴影内置是一种可怕的做法。

@ShadowRanger我修好了。

你做了,但新代码在一般情况下有自己的问题(对于两个tuple情况确实没有问题),因为错误的值会被该测试误认为重复(a list喜欢[1, None, 0, 2],没有重复的,仍然会减少到[1, 2],因为None和0看起来像这个逻辑的重复。您可以执行if x not in new: new.append(x)并避免to_append临时,并且可能会混淆重复值的伪值。

@ShadowRanger thx,固定。

投票已被删除。 :-)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值