2 回答
TA贡献1836条经验 获得超5个赞
由于您的列表可能有重复项:
from itertools import combinations
nums = [1, 2, 3, 3]
# get combinations of all possible lengths
combos = []
for n in range(len(nums)):
combos += combinations(nums, n)
# create the pairs you want, but with all nums
combo_pairs = [(combo, list(nums)) for combo in combos]
# remove the nums that are in the combination for each pair
for combo, combo_nums in combo_pairs:
for n in combo:
combo_nums.remove(n)
print(combo_pairs)
注意:这将导致重复值重复(一个对应一个三个,一个对应另一个)。你可以摆脱这样的:
combo_pairs = list(set([(combo, tuple(combo_nums)) for combo, combo_nums in combo_pairs]))
这会将对中的 nums 变成一个元组,因为元组是可散列的,但列表不是。当然,如果需要,您可以随时转换回列表。
如果您只对长度比原始长度小 1 的组合感兴趣,您可以这样做:
from itertools import combinations
nums = [1, 2, 3, 3]
# get combinations of correct length
combos = combinations(nums, len(nums)-1)
# create the pairs you want, but with all nums
combo_pairs = [(combo, list(nums)) for combo in combos]
# remove the nums that are in the combination for each pair
for combo, combo_nums in combo_pairs:
for n in combo:
combo_nums.remove(n)
print(combo_pairs)
但在这种情况下,您也可以:
nums = [1, 2, 3, 3]
combos = [(nums[:n] + nums[n+1:], [nums[n]]) for n in range(len(nums))]
TA贡献1890条经验 获得超9个赞
由于组合的其余部分由“排除”的元素唯一确定,因此您实际上并不需要 itertools。
def combinations_leaving_one_out(lst):
lst = sorted(lst)
prev_x = None
for i, x in enumerate(lst):
if x != prev_x:
yield tuple(lst[:i] + lst[i+1:]), x
prev_x = x
例子:
>>> lst = [1, 2, 3, 1, 2, 4]
>>> for comb, left_out in combinations_leaving_one_out(lst):
... print(comb, left_out)
...
(1, 2, 2, 3, 4) 1
(1, 1, 2, 3, 4) 2
(1, 1, 2, 2, 4) 3
(1, 1, 2, 2, 3) 4
添加回答
举报