为什么此L系统代码不返回字符串?

时间:2019-07-13 12:04:40

标签: python string l-systems

我正在尝试编写一个程序,该程序需要一个字符串并将某些字符替换为其他字符串。 (A-> AB)和(B-> A)。当我运行它时,我希望返回最后一个字符串,但是什么也不返回。

def createSystem(seed,depth):

    startString = seed
    endString = ""

    for i in range(depth): 
        endString = processString(startString)
        startString = endString
    return endString   


def processString(oldstr):
    newstr=""
    for char in oldstr:
        newstr=newstr+applyrules(oldstr)

    return(newstr)

def applyrules(oldstr):
    output=""

    for char in oldstr:
        if char=="A":
            output.join("AB")
        elif char=="B":
            output.join("A")

    return(output)


print(createSystem("AB",1))

在此示例中,我希望种子“ AB”产生字符串“ ABA”,但是不会向控制台返回任何内容。为什么是这样?提前致谢! -以利

编辑:程序会编译,不会产生任何错误。

1 个答案:

答案 0 :(得分:0)

例如,您似乎期望

output = ""
output.join("AB")

表示:“ output是一个空字符串;现在使output成为在现有'AB'末尾添加output的结果。”

不是。

这意味着:“ output是一个空字符串;现在通过将现有的output放在'AB'的每个字符之间来创建一个新字符串,并将该新字符串扔掉(不要不要给它起个名字。”

在Python中,字符串是不可变 -您对字符串所做的任何操作都不能就地更改其内容,例如使用列表。您必须使用创建新字符串的操作,然后重新分配结果。另外,join方法用于获取整个 个字符串序列,并将它们连接在一起,例如:

' '.join(['a', 'b', 'c']) # produces 'a b c'

代码不会引发错误,因为Python字符串也是有效的字符串序列(每个字符串都包含一个字符)。这是字符串的一种特殊行为,未被其他序列共享。

要在此处使用该方法,您需要生成'AB''A'片段的序列,然后调用''.join(即,我们在每个片段之间放置一个空字符串)直接获取结果。我们可以使用generator expression来做到这一点。看起来像这样:

def process_string(oldstr):
    return ''.join(
        'AB' if char == 'A' else 'A'
        for char in oldstr
    )

(请注意该函数的命名约定-有关Python中的标准样式约定,请参见PEP 8

这实际上就是您所需要的。 或者您可以应用原始代码中考虑的+ =逻辑,一次构建一个字符串(此is less efficient):

def process_string(oldstr):
    newstr = ''
    for char in oldstr:
        newstr += 'AB' if char == 'A' else 'A'
    return newstr # parentheses are meaningless here.

或者,您可以使用字符串类已经提供的对这种字符串转换的内置支持(但这比应该的要笨拙):

def process_string(oldstr):
    return oldstr.translate(str.maketrans({'A': 'AB', 'B': 'A'}))

在这里,str.maketrans调用一个属于字符串类的类方法(名为str,并且从启动时就可以作为全局方法自动使用)。您可以在语言文档中阅读以下方法:str.translate; str.maketrans

您似乎感到困惑,并试图同时做两件事。试图将转换规则的逻辑放入单独的函数(applyrules)中,但此函数将需要返回只是对应于单个输入字符的片段。 (毕竟,您已经设置好遍历字符,并设计了applyrules一次可以接受一个字符。)它所做的工作很简单,至少在目前为止,是一个单独的函数并不是必须的(除非它可以帮助您理解代码)。

在以上示例中,我使用了ternary conditional operator来表示为每个输入字符选择替换片段的逻辑。这对于生成器表达式方法是必需的,因为您正在编写单个 expression ,并且无处放置if: / else:块。