V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
zckun
V2EX  ›  Python

Python 排列组合生成

  •  
  •   zckun · 2020-09-13 22:12:37 +08:00 · 1720 次点击
    这是一个创建于 1530 天前的主题,其中的信息可能已经有所发展或是发生改变。

    老哥们, 请教一个问题, 是关于排列组合的, 前几天和老哥们讨论了一下, 能是能解决, 但感觉不太方便 看一个简单的例子应该就明白了.

    <school type="primary|middle|university">
        <class number="1"/>
    </school>
    

    to

    <school type="primary">
        <class number="1"/>
    </school>
    
    <school type="middle">
        <class number="1"/>
    </school>
    
    <school type="university">
        <class number="1"/>
    </school>
    

    目前是我这样做的, 用了一个模版 template

    <school type="{school_type}">
        <class number="{class_number}"/>
    </school>
    

    代码和上面的学校例子有点不同,因为我的完整需求是这样的

    <!-- base -->
    <cross>
        <rule1 hint="rule 1" name="long" val1="30|60" val2="90|120" condition="1">
            <necessary_rule val1="60" val2="120" condition="1"/>
        </rule1>
    </cross>
    
    <!-- generator -->
    <!-- 1 -->
    <cross>
        <rule1 hint="rule 1" name="long" val1="30" val2="90" condition="1">
            <necessary_rule val1="60" val2="120" condition="1"/>
        </rule1>
    </cross>
    
    <!-- 2 -->
    <cross>
        <rule1 hint="rule 1" name="long" val1="30" val2="120" condition="1">
            <necessary_rule val1="60" val2="120" condition="1"/>
        </rule1>
    </cross>
    
    <!-- 3 -->
    <cross>
    <rule1 hint="rule 1" name="long" val1="60" val2="90" condition="1">
        <necessary_rule val1="60" val2="120" condition="1"/>
    </rule1>
    </cross>
    
    <!-- 4 -->
    <cross>
    <rule1 hint="rule 1" name="long" val1="60" val2="120" condition="1">
        <necessary_rule val1="60" val2="120" condition="1"/>
    </rule1>
    </cross>
    
    

    代码

    import xml.etree.ElementTree as ET
    import itertools
    
    from typing import Dict, Optional
    
    
    def producer(rule, root_tag: Optional[str] = ''):
        rule_tag = rule.tag
        rule_temp = {}
        rule_attrib = rule.attrib
        for k, v in rule_attrib.items():
            k = f'{root_tag}{rule_tag}_{k}'
            if 'val' in v:
                v = rule_attrib.get(v)
            rule_temp[k] = v.split('|')
        return rule_temp
    
    
    def params_parser():
        tree = ET.parse('rule.xml')
        rule_params = {}
        root = tree.getroot()
        for strategy in root:
            for rule in strategy:
                rule_params.update(**producer(rule))
                for child_rule in rule:
                    rule_params.update(**producer(child_rule, root_tag=f'{rule.tag}_'))
    
        return rule_params
    
    
    def rule_generator(rule_params: Dict):
        with open('rule_template.xml', encoding='utf-8') as f:
            template = f.read()
    
        for values in itertools.product(*rule_params.values()):
            params = dict(zip(rule_params.keys(), values))
            data = template.format(**params)
            print(data)
    
    
    def main():
        rule_params = params_parser()
        rule_generator(rule_params)
    
    
    if __name__ == '__main__':
        main()
    

    我的思路是取出所有 tag 的 attrib,然后替换到模版. 上面的做法能解决我的问题,但这样每次都要弄一个模版我觉得很麻烦,有没有更简洁的办法

    7 条回复    2020-09-14 00:56:12 +08:00
    reter
        1
    reter  
       2020-09-13 22:40:37 +08:00
    试一下用 html 模板库生成?比如 moko 或 jinja
    应该两个循环就能完成
    zckun
        2
    zckun  
    OP
       2020-09-13 22:50:58 +08:00
    @reter 。。一时没想到 jinja
    uti6770werty
        3
    uti6770werty  
       2020-09-14 00:15:08 +08:00
    搭车请教个问题,如果是以
    testStr = string.Template('$who is $role')
    如果 string 里面有过百个$模板变量,
    是否可以以字典的方式传入替换?
    testDict = {'who':'Tom,'role':'cat'}
    这样去完成呢? 也不想启用 jinja 相对比较“重"利器去完成。。。
    zckun
        4
    zckun  
    OP
       2020-09-14 00:23:28 +08:00
    @uti6770werty 编程珠玑 26 页 3.2 格式信函编程和你这类似
    Pagliacii
        5
    Pagliacii  
       2020-09-14 00:25:54 +08:00
    Pagliacii
        6
    Pagliacii  
       2020-09-14 00:30:37 +08:00
    @Pagliacii #5 s.substitute(d) 也是可以的
    imn1
        7
    imn1  
       2020-09-14 00:56:12 +08:00
    @uti6770werty #3
    可以
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   984 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 20:24 · PVG 04:24 · LAX 12:24 · JFK 15:24
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.