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

Why Isn't This L-System Code Returning a String?

我正在尝试编写一个程序,它接受一个字符串并将某些字符替换为其他字符串。 (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",但是没有任何内容返回到控制台。为什么是这样?提前致谢! - 伊莱

编辑:程序编译并且没有产生任何错误。

您似乎希望,例如,

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

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

没有。

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

在 Python 中,字符串是 不可变的 - 你对它们做的任何事情都不能改变它们的内容 in-place,就像列表一样。您必须使用创建新字符串的操作,并重新分配结果。此外,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
    )

(注意函数的命名约定 - 请参阅 PEP 8 了解 Python 中的标准样式约定)

这就是您真正需要的。 你可以应用你在原始代码中想到的+=逻辑,一次构建一个字符串(这个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.

你可以使用built-in对字符串class已经提供的这种字符串翻译的支持(但这比它更尴尬应该是):

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

此处,str.maketrans 调用属于字符串 class 的 class 方法(名为 str 并从启动时自动作为全局变量使用)。您可以在语言文档中阅读这些方法:str.translate; str.maketrans.

看来您感到困惑并试图同时做这两件事。感谢您尝试将转换规则的逻辑放入一个单独的函数 (applyrules),但该函数需要 return 只是对应于单个输入字符的片段 。 (毕竟,您已经设置好迭代字符,并设计 applyrules 一次接受一个字符。)它所做的工作非常简单——至少现在是——一个单独的函数并不是真的有必要(除非它可以帮助您理解代码)。

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