当顺序很重要时(并将每个结果分配给一个唯一的键),迭代多个结果的最干净的方法是什么?

2024-10-01 09:41:45 发布

您现在位置:Python中文网/ 问答频道 /正文

目前,我正在尝试用python编写一个空页面,并使用python中的内置字典。我正在阅读每一行,如果字典中没有这一行,我会把它添加到字典中

但是,我没有时间手动编写每个可能的组合,但非常重要的是,我能够为每个可能的组合分配自己的唯一键

为了解决这个问题,我尝试了以下方法:

while x <= number_of_outcomes:
        print("{0}\t{1}\t{2}\t{3}".format(value1, value2, value3, value4),file=outfile)
        nvalue1 = value1
        nvalue2 = value2
        nvalue3 = value3
        nvalue4 = value4
        nvalue1 = 0
        print("{0}\t{1}\t{2}\t{3}".format(nvalue1, nvalue2, nvalue3, nvalue4),file=outfile)
        while nvalue1 == 0:
            ###print("{0}\t{1}\t{2}\t{3}".format(value1, value2, value3, value4),file=outfile)
            if nvalue4 == 2:
                break
            else:
                for i in setoftwo:
                    ###nvalue2 = nvalue2 + 1
                    ###print("{0}\t{1}\t{2}\t{3}".format(nvalue1, nvalue2, nvalue3, nvalue4),file=outfile)
                    mvalue1 = nvalue1
                    mvalue2 = nvalue2
                    mvalue3 = nvalue3
                    mvalue4 = nvalue4
                    if mvalue2 == 1:
                        for i in setoftwo:
                            mmvalue1 = mvalue1
                            mmvalue2 = mvalue2
                            mmvalue3 = mvalue3
                            mmvalue4 = mvalue4
                            if mmvalue3 == 1:
                                for i in setoftwo:
                                    mmvalue4 = mmvalue4 + 1
                                    print("{0}\t{1}\t{2}\t{3}".format(mmvalue1, mmvalue2, mmvalue3, mmvalue4),file=outfile)
                            mvalue3 = mvalue3 + 1
                            print("{0}\t{1}\t{2}\t{3}".format(mvalue1, mvalue2, mvalue3, mvalue4),file=outfile)
                        for i in setoftwo:
                            mvalue4 = mvalue4 + 1
                            print("{0}\t{1}\t{2}\t{3}".format(nvalue1, nvalue2, nvalue3, nvalue4),file=outfile)
                            
                    nvalue2 = nvalue2 + 1
                    print("{0}\t{1}\t{2}\t{3}".format(nvalue1, nvalue2, nvalue3, nvalue4),file=outfile)
                for i in setoftwo:
                    nvalue3 = nvalue3 + 1
                    print("{0}\t{1}\t{2}\t{3}".format(nvalue1, nvalue2, nvalue3, nvalue4),file=outfile)
                for i in setoftwo:
                    nvalue4 = nvalue4 + 1
                    print("{0}\t{1}\t{2}\t{3}".format(nvalue1, nvalue2, nvalue3, nvalue4),file=outfile)

我一直遇到打印所有内容的第一个值“0”的问题,我通过为每个嵌套提供自己的值“新版本”,然后迭代该值来解决这个问题

然而,在4个值的深度,我意识到我不可能对256个值使用这种方法,至少在我有生之年不可能

目标是最终生成一个字典,其中字典中的每个键都引用一个数字/字母字符串,并且每个键都只有3个选项中的1个,如果选择了第三个选项,则其他数字/字母可能没有该选项

因此,在20个数字长的情况下,可能会有一个类似“010102011110100000”或“abababbbabaaaa”的定义,它是唯一的,由1个键定义

在简单的长度为4时,我开始注意到我缺少值(比如0112,使用我的方法我可以得到0221,但是我必须在每个1赋值后做一个if语句,如果值为1,则迭代下一个值,如果值为1,则迭代下一个值)(这已经很冗长了,我当时就知道这是行不通的)

这让我大吃一惊,因为我有一个手绘参考,总共8页(大约20页),并且决定也许编码会更容易,但我不知道如何轻松地移动“unique”值,以便每个unique值在每个可能的组合中都有0,1或a,b

2个值将打印出来 CA(01) CB(02) 机管局(11) AB(12) BB(22) 文学士(21) BC(20) AC(10)

3个值看起来像

民航局(011) 驾驶室(012) CBB(022) CBA(021) AAA(111) ABB(122) ABA(121) AAB(112) ……等等。。。 美国银行(210) AAC(110)

最后,在一个完美的世界中,如果键11、111或1111存在,那么键22、222或2222就不存在了(或者反之亦然),因为它们是等效的,但在最坏的情况下,我可以在生成后手动从字典中删除它们

我不知道键的长度最终会有多长,我实际上是想通过使用较小的长度和python来预测它,因为我在绘制它时希望找到一个模式,但开始丢失键序列,并且必须擦除半页才能将其放在正确的位置(试图从视觉上看到某种模式)

为了将来的目的,能够在一个长链中有2或3个独特的角色将是令人惊讶的,因此任何允许将来修改以轻松模拟2或3个独特角色如何玩的建议都将是令人惊讶的

我面前有一本来自大学的python教科书,我一直在搜索引擎上下搜索,试图看看某种概率和统计页面是否会启发我,我知道我缺乏经验可能是我无法找到我要找的答案的原因,所以如果我错过了一个简单明了的解决方案,谢谢你的好意我想让我知道


Tags: informatforif字典outfilefileprint
1条回答
网友
1楼 · 发布于 2024-10-01 09:41:45

我认为这解决了您的基本问题(一个独特的值):

from itertools import product

base_values = ['A', 'B']  # = 'AB' is also possible
unique_value = 'C'
key_len = n

keys = {
    ''.join(key)
     for key in product(base_values, repeat=key_len)
}
keys.remove(base_values[-1] * key_len)
keys |= {
    ''.join(key[:i] + (unique_value,) + key[i:])
    for key in product(base_values, repeat=key_len-1)
    for i in range(key_len)
}

key_len = 2的结果

{'AA', 'AB', 'AC', 'BA', 'BC', 'CA', 'CB'}

key_len = 3

{'AAA', 'AAB', 'AAC', 'ABA', 'ABB', 'ABC', 'ACA', 'ACB', 'BAA', 'BAB',
 'BAC', 'BBA', 'BBC', 'BCA', 'BCB', 'CAA', 'CAB', 'CBA', 'CBB'}

更一般的问题有点棘手。以下是一个解决方案(至少我认为是一个):

from itertools import product, combinations, combinations_with_replacement, permutations

base_values = ['A', 'B']  # = 'AB' is also possible
unique_values = ['C', 'D', 'E']  # = 'C...' is also possible
key_len = n

keys = set()
for unique_len in range(min(key_len, len(unique_values)) + 1):
    uniques = combinations(unique_values, unique_len)
    base = combinations_with_replacement(base_values, key_len - unique_len)
    keys |= {
        ''.join(key)
        for ukey, bkey in product(uniques, base)
        for key in permutations(ukey + bkey)
    }
keys.remove(base_values[-1] * key_len)

但是permutations的使用是次优的,如果bkey包含多个密钥,它会生成多个相同的密钥,然后由集合构建统一。我知道如何以一种混乱的方式解决这个问题。我会在提出更好的解决方案时更新(如果您感兴趣的话)

此版本速度快得多,但不幸的是不是超级可读:

from itertools import product, combinations, permutations

base_values = ['A', 'B']  # = 'AB' is also possible
unique_values = ['C', 'D', 'E']  # = 'C...' is also possible
key_len = n

def positioning(u_pos, k_len):
    b_pos = sorted(set(range(k_len)).difference(u_pos))
    u_len = len(u_pos)
    return {
        **{p: i for i, p in enumerate(u_pos)},
        **{b_pos[j]: i for i, j in zip(range(u_len, k_len), range(k_len - u_len))}
    }

keys = set()
for u_len in range(min(key_len, len(unique_values)) + 1):
    u_keys = [
        u_key + b_key
        for u_key, b_key in product(
                                combinations(unique_values, u_len),
                                product(base_values, repeat=key_len-u_len)
                            )
    ]
    for u_pos in permutations(range(key_len), u_len):
        pos = positioning(u_pos, key_len)
        keys |= {
            ''.join(key[pos[i]] for i in range(key_len))
            for key in u_keys
        }
keys.remove(base_values[-1] * key_len)

相关问题 更多 >