python中的多组联盟

Tap*_*dal 15 python list python-3.x set-union

[[1, '34', '44'], [1, '40', '30', '41'], [1, '41', '40', '42'], [1, '42', '41', '43'], [1, '43', '42', '44'], [1, '44', '34', '43']]
Run Code Online (Sandbox Code Playgroud)

我有一份清单清单.我的目的是检查是否有任何一个子列表与其他子列表有任何共同点(不包括要比较的第一个索引对象).如果它有任何共同点,那么统一这些子列表.

例如,对于这个例子,我的最终答案应该是这样的:

[[1, '34, '44', '40' '30', '41', '42', '43']]
Run Code Online (Sandbox Code Playgroud)

我可以理解我应该将子列表转换为集合,然后使用union()和intersection()操作.但我坚持的是如何比较每个集/子列表.我不能在列表上运行循环并逐个比较每个子列表,因为列表的内容将被修改,这将导致错误.

我想知道的是有没有有效的方法来比较所有子列表(转换为集合)并获得它们的并集?

Ray*_*ger 29

itertools模块使得这个问题的短期工作:

>>> from itertools import chain
>>> list(set(chain.from_iterable(d)))
[1, '41', '42', '43', '40', '34', '30', '44']
Run Code Online (Sandbox Code Playgroud)

另一种方法是将列表解压缩为union()的单独参数:

>>> list(set().union(*d))
[1, '41', '42', '43', '40', '34', '30', '44']
Run Code Online (Sandbox Code Playgroud)

后一种方法消除了所有重复,并且不要求首先将输入转换为集合.此外,它不需要导入.

  • 你最好编写“set.union()”,因为“set()”用空集初始化。在这种情况下这是可以的,但我花了很多时间寻找错误,因为我认为这可以推广到交叉点。使用“set.”,您可以进行并集和交集! (3认同)
  • ``chain.from_iterable()`` 步骤是尺度不变的。在任何给定时间,它的整个状态都存储在两个指向迭代器的指针中。``set()`` 和 ``list()`` 部分占用的内存与唯一输入的总数成正比。在我的 64 位机器上,一亿个唯一输入需要 4.3 GB 的 RAM 用于设置对象和 0.9 GB 用于列表对象。 (2认同)

Ami*_*ory 20

使用解包操作符*:

>> list(set.union(*map(set, a)))
[1, '44', '30', '42', '43', '40', '41', '34']
Run Code Online (Sandbox Code Playgroud)

(感谢Raymond Hettinger的评论!)

(注意

set.union(*tup)
Run Code Online (Sandbox Code Playgroud)

将打开包装

set.union(tup[0], tup[1], ... tup[n - 1])
Run Code Online (Sandbox Code Playgroud)

)

  • 您可以通过将 `set.union(*map(set, a))` 更改为 `set().union(*a)` 来显着减少临时 `set` 的数量。需要 `map(set,` 的唯一原因是因为你正在调用 `set.union` 并且第一个参数变成了它被调用的“self”,但是如果你将一个空的 `set` 作为基础, `union` 接受剩余参数的任意迭代。 (3认同)
  • FWIW,*元组*步骤无效,因为星形解包对任何可迭代都有效.你也可以用``map(set,a)``替换list comprehension.结果归结为``list(set.union(*map(set,a)))``. (2认同)