可以在字典理解过程中过滤重复值吗?



我正在创建一个以索引为键的随机坐标字典,并且坐标必须是唯一的。

我知道我可以在创建字典后返回并过滤字典键中的重复项,但是是否可以确保在通过理解创建字典的过程中没有重复项?

在伪代码中,我想做这样的事情:

d = {k: (randint,randint) for k in range if (randint,randint) not in d}

但这在赋值之前引用字典 d。

需要明确的是,我是通过理解创建字典,而不是修改现有字典。

如注释中所述,您应该使用循环。

如果你想使用一些技巧,你有旧的技术:

>>> from random import randint, seed
>>> seen = set()
>>> {k: (x, y) for k, x, y in ((k, randint(0,5),randint(0,5)) for k in range(50)) if (x, y) not in seen and not seen.add((x, y))}
{0: (3, 4), 1: (3, 3), 2: (4, 4), 3: (1, 1), 4: (4, 3), 5: (5, 4), 6: (1, 0), 7: (3, 2), 9: (4, 5), 10: (5, 0), 12: (3, 5), 14: (5, 1), 15: (4, 0), 17: (0, 0), 22: (1, 4), 23: (1, 5), 24: (2, 3), 25: (0, 5), 26: (0, 3), 27: (5, 2), 30: (2, 2), 32: (2, 0), 33: (0, 4), 35: (0, 2), 36: (3, 0), 38: (0, 1), 41: (5, 3)}

生成器((k, randint(0,5),randint(0,5)) for k in range(50))生成 50 个带有索引的坐标。元组k, x, ,y被测试:if (x, y) not in seen,我们计算and的第二部分:seen.add((x, y)返回None,因此not seen.add((x, y)总是True,但执行一个副作用(将元素添加到seen(。

缺点是字典的大小取决于重复项的数量。要选择元素的数量,您必须:1.创建一个虚拟生成器;2. 取 N 个唯一元素。

您可以使用iter函数和假哨兵创建一个无限生成器((-1, -1)永远不会产生(:

>>> it = iter(lambda: (randint(0,5),randint(0,5)), (-1, -1))

现在,使用itertools标准模块,您可以获取前 10 个元素,而不会重复:

>>> import itertools
>>> seen = set()
>>> dict(enumerate(itertools.islice(((x,y) for x, y in it if (x, y) not in seen and not seen.add((x, y))), 10)))
{0: (5, 0), 1: (0, 0), 2: (3, 3), 3: (1, 5), 4: (4, 1), 5: (3, 4), 6: (1, 3), 7: (5, 3), 8: (0, 3), 9: (3, 1)}

但是你应该使用循环...

最新更新