Python-从列表中创建所有可能性

时间:2019-09-02 17:57:50

标签: python

所以我有一个列表:

blocks = ["air", "emerald_block"]

我用它们创建命令,并且我想替换这些句子中的字符串以创建可以从列表中得出的所有可能性。

示例: 输入:

max_number = 2
blocks = ["air", "emerald_block"]

输出:

execute as @e[type=minecraft:armor_stand, name=bridge] at @s if block ^ ^-1 ^1 minecraft:air if block ^ ^-1 ^2 minecraft:air run tp @s ^ ^ ^2
execute as @e[type=minecraft:armor_stand, name=bridge] at @s if block ^ ^-1 ^1 minecraft:emerald_block if block ^ ^-1 ^2 minecraft:air run tp @s ^ ^ ^2
execute as @e[type=minecraft:armor_stand, name=bridge] at @s if block ^ ^-1 ^1 minecraft:air if block ^ ^-1 ^2 minecraft:emerald_block run tp @s ^ ^ ^2
execute as @e[type=minecraft:armor_stand, name=bridge] at @s if block ^ ^-1 ^1 minecraft:emerald_block if block ^ ^-1 ^2 minecraft:emerald_block run tp @s ^ ^ ^2

那是我的代码:

max_number = 2
blocks = ["air", "emerald_block"]
command = "execute as @e[type=minecraft:armor_stand, name=bridge] at @s {0}run tp @s ^ ^ ^{1}"
insert_string = "INSERTHERE"


def create_positions(ran, command="if block ^ ^-1 ^{} minecraft:{} "):
    cmd = ""
    cmd += command.format(ran, insert_string)
    if ran > 1:
        cmd += create_positions(ran - 1, command)
    return cmd


c = ""

for i in range(1, max_number * len(blocks) + 1):
    c += command.format(create_positions(max_number), max_number) + "\n"


print(c)

for sentence in c:
    pass
    #I think here belongs the code to replace the string

1 个答案:

答案 0 :(得分:1)

如果我正确理解,这就是您想要的:

import itertools

max_number = 3

blocks = ["air", "emerald_block"]
block_check_part = "if block ^ ^-1 ^{} minecraft:{}"
single_command = "execute as @e[type=minecraft:armor_stand, name=bridge] at @s {} run tp @s ^ ^ ^{}"
commands = []

for combination in itertools.product(blocks, repeat=max_number):
    block_check_parts = [block_check_part.format(i + 1, b) for i, b in enumerate(combination)]
    block_checks_command = " ".join(block_check_parts)
    command = single_command.format(block_checks_command, max_number)
    commands.append(command)

final_command = "\n".join(commands)
print(final_command)

for循环正在进行中,所以这里是逐位解释:

for combination in itertools.product(blocks, repeat=max_number):

itertools是一个非常有用的模块,它可以通过各种可能性进行组合/排列/循环来执行类似的操作。 product()函数可创建一组可迭代对象的笛卡尔积。因为我们希望同一组事物(blocks列表)多次与自身组合,所以可以使用repeat参数。

如果我们将其打印出来,我们可以看到它在做什么:

>>> print(*itertools.product(blocks, repeat=max_number), sep="\n")
('air', 'air', 'air')
('air', 'air', 'emerald_block')
('air', 'emerald_block', 'air')
('air', 'emerald_block', 'emerald_block')
('emerald_block', 'air', 'air')
('emerald_block', 'air', 'emerald_block')
('emerald_block', 'emerald_block', 'air')
('emerald_block', 'emerald_block', 'emerald_block')

我们在每个位置上都有'air''emerald_block'的每种组合。实际上,这是核心部分,在我们创建了这些组合之后,这只是一个循环遍历它们并将它们正确放入命令模板的问题:

    # loop through this block combination with a number for each and make into a command
    # e.g. the combination ('air', 'emerald_block', 'air') becomes the list
    # [
    #     "if block ^ ^-1 ^1 minecraft:air",
    #     "if block ^ ^-1 ^2 minecraft:emerald_block",
    #     "if block ^ ^-1 ^3 minecraft:air",
    # ]
    block_check_parts = [block_check_part.format(i + 1, b) for i, b in enumerate(combination)]

    # join these parts together with a space between them, e.g.:
    # "if block ^ ^-1 ^1 minecraft:air if block ^ ^-1 ^2 minecraft:emerald_block if block ^ ^-1 ^3 minecraft:air"
    block_checks_command = " ".join(block_check_parts)

    # put into the main command
    command = single_command.format(block_checks_command, max_number)

    # add to the list of commands so far
    commands.append(command)

# join all these commands together into one text list
final_command = "\n".join(commands)
print(final_command)

说实话,这似乎是一种漫长的方法来完成您要实现的目标。可能有一种更快的方法来执行此操作,但是我不知道Minecraft命令的范围能够提出好的建议。

不过,我遇到了这个问题,可能是类似的:https://www.reddit.com/r/Minecraft/comments/a8hbli/can_someone_tell_me_how_the_113_execute_if_blocks/