草庐IT

python - 在计算之前删除包含某些值的组合

coder 2023-05-26 原文

给定一个列表和排除元素,是否可以忽略包含这些元素的组合计算?

示例 1

给定 l = [1, 2, 3, 4, 5],我想计算 size 4 的所有组合,不包括包含 ( 1, 3) 甚至在计算之前。

结果是:

    All results:            Wanted results:

    [1, 2, 3, 4]            [1, 2, 4, 5]
    [1, 2, 3, 5]            [2, 3, 4, 5]
    [1, 2, 4, 5]
    [1, 3, 4, 5]
    [2, 3, 4, 5]

所有包含 1 和 3 的组合均已删除。

示例 2

@Eric Duminil 建议

l = [1, 2, 3, 4, 5, 6]size 4

的结果
  • 不包括第二列中的(1, 2, 3)
  • 不包括第三列的(1, 2)

    All results:        Wanted results 1            Wanted results 2
                        (Excluding [1, 2, 3]):      (Excluding [1, 2])
    
    [1, 2, 3, 4]        [1, 2, 4, 5]                [1, 3, 4, 5]
    [1, 2, 3, 5]        [1, 2, 4, 6]                [1, 3, 4, 6]
    [1, 2, 3, 6]        [1, 2, 5, 6]                [1, 3, 5, 6]
    [1, 2, 4, 5]        [1, 3, 4, 5]                [1, 4, 5, 6]
    [1, 2, 4, 6]        [1, 3, 4, 6]                [2, 3, 4, 5]
    [1, 2, 5, 6]        [1, 3, 5, 6]                [2, 3, 4, 6]
    [1, 3, 4, 5]        [1, 4, 5, 6]                [2, 3, 5, 6]
    [1, 3, 4, 6]        [2, 3, 4, 5]                [2, 4, 5, 6]
    [1, 3, 5, 6]        [2, 3, 4, 6]                [3, 4, 5, 6]
    [1, 4, 5, 6]        [2, 3, 5, 6]                                
    [2, 3, 4, 5]        [2, 4, 5, 6]                                
    [2, 3, 4, 6]        [3, 4, 5, 6]                                
    [2, 3, 5, 6]           
    [2, 4, 5, 6]           
    [3, 4, 5, 6]        
    

所有包含 1 和 2 和 3 的组合都已从想要的结果 1 中删除

所有包含 1 和 2 的组合都已从想要的结果 2 中删除

我有更大的组合要计算,但这需要很多时间,我想使用这些排除项来减少这个时间。

尝试过的解决方案

使用方法1,仍然计算组合

使用方法2,我尝试修改combinations function但我找不到合适的方法在计算之前忽略我的排除列表。

            Method 1                    |               Method 2
                                        |               
def main():                             |   def combinations(iterable, r):
    l = list(range(1, 6))               |       pool = tuple(iterable)
    comb = combinations(l, 4)           |       n = len(pool)
                                        |       if r > n:
    for i in comb:                      |           return
        if set([1, 3]).issubset(i):     |       indices = list(range(r))
            continue                    |       yield tuple(pool[i] for i in indices)
        else                            |       while True:
            process()                   |           for i in reversed(range(r)):
                                        |               if indices[i] != i + n - r:
                                        |                   break
                                        |               else:
                                        |                   return
                                        |           indices[i] += 1
                                        |           for j in range(i+1, r):
                                        |               indices[j] = indices[j-1] + 1
                                        |           yield tuple(pool[i] for i in indices)

编辑:

首先,谢谢大家的帮助,我忘了提供更多关于约束的细节。

  • 输出的顺序不相关,例如,如果结果是 [1, 2, 4, 5] [2, 3, 4, 5] [2, 3, 4, 5] [1, 2, 4, 5],不重要。

  • 组合的元素应该(如果可能)排序,[1, 2, 4, 5] [2, 3, 4, 5] 而不是 [ 2, 1, 5, 4] [3, 2, 4, 5] 但这并不重要,因为可以对组合进行排序。

  • 排除列表是不应出现组合一起的所有项目的列表。例如,如果我的排除列表是 (1, 2, 3),则不应计算包含 1 and 2 and 3 的所有组合。但是,允许使用 1 和 2 而不是 3 的组合。在这种情况下,如果我排除包含 (1, 2)(1, 2, 3) 的组合,它完全没用,因为所有组合都将被 (1, 2, 3) 已经被 (1, 2)

  • 过滤
  • 多个排除列表必须是可能的,因为我对我的组合使用了多个约束。

测试答案

@tobias_k 此解决方案将排除列表 (1, 2, 3) 视为 OR 排除意味着 (1, 2), (2, 3) 和 (1, 3) 将是如果我理解得很好,则排除在外,这在一个案例中很有用,但在我当前的问题中没有,我修改了问题以提供更多细节,抱歉造成混淆。在您的回答中,我不能仅使用列表 (1, 2)(1, 3) 作为您指定的排除项。然而,这种解决方案的一大优势是允许多重排除。

@Kasramvd 和 @mikuszefski 您的解决方案非常接近我想要的,如果它确实包含多个排除列表,那就是答案。

谢谢

最佳答案

(事实证明这并不完全符合 OP 的要求。仍然将其留在这里,因为它可能对其他人有所帮助。)


要包含互斥元素,您可以将它们包装在列表中的列表中,获取 combinations其中,然后是 product子列表的组合:

>>> from itertools import combinations, product
>>> l = [[1, 3], [2], [4], [5]]
>>> [c for c in combinations(l, 4)]
[([1, 3], [2], [4], [5])]
>>> [p for c in combinations(l, 4) for p in product(*c)]
[(1, 2, 4, 5), (3, 2, 4, 5)]

一个更复杂的例子:

>>> l = [[1, 3], [2, 4, 5], [6], [7]]
>>> [c for c in combinations(l, 3)]
[([1, 3], [2, 4, 5], [6]),
 ([1, 3], [2, 4, 5], [7]),
 ([1, 3], [6], [7]),
 ([2, 4, 5], [6], [7])]
>>> [p for c in combinations(l, 3) for p in product(*c)]
[(1, 2, 6),
 (1, 4, 6),
 ... 13 more ...
 (4, 6, 7),
 (5, 6, 7)]

这不会生成任何以后要过滤掉的“垃圾”组合。但是,它假定您最多需要每个“独占”组中的一个元素,例如在第二个示例中,它不仅阻止与 2,4,5 的组合,还阻止与 2,44,5 的组合,或 2,5。此外,不可能(或至少不容易)只拥有 1,31,5 之一,但允许 3,5 。 (也许可以将其扩展到这些情况,但我还不确定是否以及如何。)


您可以将其包装在一个函数中,从您的(假定的)格式派生出稍微不同的输入格式并返回一个一致的生成器表达式。这里,lst 是元素列表,r 是每个组合的项目数,exclude_groups 是互斥元素组的列表:

from itertools import combinations, product

def comb_with_excludes(lst, r, exclude_groups):
    ex_set = {e for es in exclude_groups for e in es}
    tmp = exclude_groups + [[x] for x in lst if x not in ex_set]
    return (p for c in combinations(tmp, r) for p in product(*c))

lst = [1, 2, 3, 4, 5, 6, 7]
excludes = [[1, 3], [2, 4, 5]]
for x in comb_with_excludes(lst, 3, excludes):
    print(x)

关于python - 在计算之前删除包含某些值的组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48616694/

有关python - 在计算之前删除包含某些值的组合的更多相关文章

  1. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  2. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  3. ruby - 我可以使用 Ruby 从 CSV 中删除列吗? - 2

    查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html

  4. ruby - 检查 "command"的输出应该包含 NilClass 的意外崩溃 - 2

    为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar

  5. ruby-on-rails - 使用一系列等级计算字母等级 - 2

    这里是Ruby新手。完成一些练习后碰壁了。练习:计算一系列成绩的字母等级创建一个方法get_grade来接受测试分数数组。数组中的每个分数应介于0和100之间,其中100是最大分数。计算平均分并将字母等级作为字符串返回,即“A”、“B”、“C”、“D”、“E”或“F”。我一直返回错误:avg.rb:1:syntaxerror,unexpectedtLBRACK,expecting')'defget_grade([100,90,80])^avg.rb:1:syntaxerror,unexpected')',expecting$end这是我目前所拥有的。我想坚持使用下面的方法或.join,

  6. ruby - 我可以使用 aws-sdk-ruby 在 AWS S3 上使用事务性文件删除/上传吗? - 2

    我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的

  7. ruby - 如何在 Rails 4 中使用表单对象之前的验证回调? - 2

    我有一个服务模型/表及其注册表。在表单中,我几乎拥有服务的所有字段,但我想在验证服务对象之前自动设置其中一些值。示例:--服务Controller#创建Action:defcreate@service=Service.new@service_form=ServiceFormObject.new(@service)@service_form.validate(params[:service_form_object])and@service_form.saverespond_with(@service_form,location:admin_services_path)end在验证@ser

  8. ruby-on-rails - 在 Rails 和 ActiveRecord 中查询时忽略某些字段 - 2

    我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr

  9. ruby - 检查字符串是否包含散列中的任何键并返回它包含的键的值 - 2

    我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案

  10. ruby - 如何安全地删除文件? - 2

    在Ruby中是否有Gem或安全删除文件的方法?我想避免系统上可能不存在的外部程序。“安全删除”指的是覆盖文件内容。 最佳答案 如果您使用的是*nix,一个很好的方法是使用exec/open3/open4调用shred:`shred-fxuz#{filename}`http://www.gnu.org/s/coreutils/manual/html_node/shred-invocation.html检查这个类似的帖子:Writingafileshredderinpythonorruby?

随机推荐