Python 将列表分组为具有约束的子组
Python group list into subgroups with constraints
我确实在搜索这个,因为我几乎可以肯定之前有人问过一些变体,但我无法在 Google 中输入正确的术语来获得与我想要的相匹配的结果做。总的来说,人们似乎在寻找不受限制的总组合。
我正在尝试执行以下操作:
给出这样的列表:
[1, 1, 2, 2, 3, 3]
尽可能多的分成[1, 2, 3]
组
所以
[1, 1, 2, 2, 3, 3]
-> [[1, 2, 3], [1, 2, 3]]
[1, 1, 2, 3, 3]
-> [[1, 2, 3], [1, 3]]
[1, 1, 3, 3, 5]
-> [[1, 3, 5], [1, 3]]
[1, 4, 4, 7]
-> [[1, 4, 7], [4]]
备注:
输入总是会被排序,但是这些数字的值是未知的,所以它需要在一般意义上工作。
我的想法是我有一些具有某些属性的对象需要组合在一起以创建一个不同的对象,但有时我会得到重复(并且可能不完整的重复)——也就是说,我曾经认为我的对象的属性总是 [1, 2, 3]
但有时我可以获得 [1, 1, 2, 2, 3, 3]
我需要一种方法将其分成两个 [1, 2, 3]
列表以在下游创建中间对象.
您可以使用 zip_longest
和 groupby
来自 itertools
:
from itertools import zip_longest, groupby
def f(l):
z = zip_longest(*[list(g) for _, g in groupby(l)])
return [[j for j in i if j is not None] for i in z]
用法:
>>> f([1, 1, 2, 2, 3, 3])
[[1, 2, 3], [1, 2, 3]]
>>> f([1, 1, 2, 3, 3])
[[1, 2, 3], [1, 3]]
>>> f([1, 1, 3, 3, 5])
[[1, 3, 5], [1, 3]]
>>> f([1, 4, 4, 7])
[[1, 4, 7], [4]]
# Update
>>> f(sorted([1, 1, 2, 2, 3, 3, 1, 2]))
[[1, 2, 3], [1, 2, 3], [1, 2]]
# Update 2
>>> f([1, 1, 1, 2, 2, 2, 3, 3])
[[1, 2, 3], [1, 2, 3], [1, 2]]
更新
@cards 使用 filterfalse
:
建议的替代版本
from itertools import zip_longest, groupby, filterfalse
def f(l):
z = zip_longest(*[list(g) for _, g in groupby(l)])
return [list(filterfalse(lambda j: j is None, i)) for i in z]
我确实在搜索这个,因为我几乎可以肯定之前有人问过一些变体,但我无法在 Google 中输入正确的术语来获得与我想要的相匹配的结果做。总的来说,人们似乎在寻找不受限制的总组合。
我正在尝试执行以下操作:
给出这样的列表:
[1, 1, 2, 2, 3, 3]
尽可能多的分成[1, 2, 3]
组
所以
[1, 1, 2, 2, 3, 3]
-> [[1, 2, 3], [1, 2, 3]]
[1, 1, 2, 3, 3]
-> [[1, 2, 3], [1, 3]]
[1, 1, 3, 3, 5]
-> [[1, 3, 5], [1, 3]]
[1, 4, 4, 7]
-> [[1, 4, 7], [4]]
备注:
输入总是会被排序,但是这些数字的值是未知的,所以它需要在一般意义上工作。
我的想法是我有一些具有某些属性的对象需要组合在一起以创建一个不同的对象,但有时我会得到重复(并且可能不完整的重复)——也就是说,我曾经认为我的对象的属性总是
[1, 2, 3]
但有时我可以获得[1, 1, 2, 2, 3, 3]
我需要一种方法将其分成两个[1, 2, 3]
列表以在下游创建中间对象.
您可以使用 zip_longest
和 groupby
来自 itertools
:
from itertools import zip_longest, groupby
def f(l):
z = zip_longest(*[list(g) for _, g in groupby(l)])
return [[j for j in i if j is not None] for i in z]
用法:
>>> f([1, 1, 2, 2, 3, 3])
[[1, 2, 3], [1, 2, 3]]
>>> f([1, 1, 2, 3, 3])
[[1, 2, 3], [1, 3]]
>>> f([1, 1, 3, 3, 5])
[[1, 3, 5], [1, 3]]
>>> f([1, 4, 4, 7])
[[1, 4, 7], [4]]
# Update
>>> f(sorted([1, 1, 2, 2, 3, 3, 1, 2]))
[[1, 2, 3], [1, 2, 3], [1, 2]]
# Update 2
>>> f([1, 1, 1, 2, 2, 2, 3, 3])
[[1, 2, 3], [1, 2, 3], [1, 2]]
更新
@cards 使用 filterfalse
:
from itertools import zip_longest, groupby, filterfalse
def f(l):
z = zip_longest(*[list(g) for _, g in groupby(l)])
return [list(filterfalse(lambda j: j is None, i)) for i in z]