1

所以以这个函数为例。

def spaced_word(s):
    i= 0
    t = s[i] + ' '

    while i < len(s) - 2:
        t = t + s[i + 1] + ' '
        i = i + 1
    t= t + s[len(s) - 1]
    return t

该函数返回输入的字符串,每个字符之间有一个空格。(例如spaced_word('hello') --> 'h e l l o'

但是,为什么要使用t = t + ...as 语句呢?

例如,为什么我不能只使用:

s[i] + ' '
i = i + 1

另外,如果我替换该行,为什么不会出现相同的结果

t = t + s[i + 1] + ' '

s[i] + ' ' + s[i + 1] + ' '

t = s[i] + ' '?

解决。感谢所有帮助过的人!

4

3 回答 3

2

您的问题似乎是关于为什么t在循环中构建字符串时需要维护一个单独的变量来保存字符串,而不是直接更改其值。

原因是 Python 的字符串是不可变的。您不能在现有字符串的两个字母之间插入空格,因为您不能修改该字符串的内容。您想要进行的任何修改都必须通过创建包含原始字符串字符副本的新字符串来完成。

您询问的代码行t = t + " " + s[i+1]执行以下操作:

  1. 首先,它创建一个新字符串,其中包含 的前一个值的副本,t并在末尾连接一个空格。这是一个临时值,不绑定到任何变量名。
  2. 然后创建第二个新字符串,复制步骤 1 中的字符串并将一个字符连接s到末尾。Python 可能足够聪明,可以重用第一步中的临时字符串,而不是复制它,但这通常不是您可以依赖的。
  3. 最后,上面第 2 步创建的字符串被绑定到变量t,替换了旧字符串(这将被垃圾收集,因为没有其他引用)。

您提出的替代代码s[i + 1] + " "创建了一个新字符串,但它没有做任何事情。它没有分配给任何东西,因此将立即被垃圾收集。重要的是要理解它s[i+1] + " "不会改变字符串s。即使尝试使用不同的语法,s[i+1] += " "它也不起作用,但在这种情况下你会得到一个异常。

这是您的代码的稍微 Pythonic 的版本,这可能会使它的功能更加清晰:

def spaced_words(s):
    result = s[0]           # start with the first letter of the string
    for c in s[1:]:         # iterate over the rest of the string
        result += " " + c   # add a space and the next character to the result
    return result           # when the loop is done, return the result string

for 循环替换了 while 循环和代码中的显式索引。这更容易遵循。我也在使用+=运算符,而不是result = result + otherstuff,但这实际上并不是主要区别。由于result字符串是不可变的,因此通常需要在每次将新值连接到末尾时复制它。但是,CPython(您从 python.org 获得的常规解释器)有一些特殊的逻辑可以以这种方式附加到字符串,实际上大部分时间都会避免复制字符串。这是一个实现细节,而不是你应该依赖的东西。

最后,我想建议使用内置str.join方法来更轻松、更高效地完成当前函数所做的事情。它接受任何可迭代对象作为其参数,并且方便地,字符串是其字符的可迭代对象:

def spaced_word(s):
    return " ".join(s)

我意识到虽然这不是你的问题,但了解 Python 的内置特性是件好事,它几乎总是比你自己编写的代码做得更好。

于 2013-06-16T03:40:36.810 回答
1

我没有详细查看您的代码,但是有一种简单的方法可以编写您正在谈论的函数:

def spaced_word( s ):
    return ' '.join( s )

print spaced_word( 'abcde' )

印刷:

a b c d e

编辑:好的,现在我查看了您的代码,看看我是否可以回答您的直接问题,答案是否定的,我不能。那个代码太复杂了。(对不起!)这种代码的复杂性应该让你退后一步,问:“没有更简单的方法吗?”

我这样说是不是很不礼貌?如果是这样,我真诚地道歉。但有时你只需要扔掉你的代码并用更简单的方法重新开始。是的,我从卑微的个人经历中知道这一点,我丢掉了很多自己的代码!

一些危险信号:

  • 有两个不同的地方将空格附加到输出字符串

  • 字符被附加到输出的三个不同的地方。字符串的第一个字符得到特殊处理,最后一个字符也是如此。

  • 运行到字符串长度减去 2的循环。

在 Python 中,就像在 Ruby 和 JavaScript 以及可能相当多的其他语言中一样,当您需要在其他一些项目之间插入一些东西时,最后没有额外的“东西”,首先要看的是join()函数或方法。在每种语言中,它接受一个数组并在每个数组元素之间插入一个字符串。这是进行这种操作的好方法。

鉴于此,剩下的唯一事情就是将原始字符串转换为数组(Python 中的列表)。你这样做的方式各不相同。在 Python 中,您可以使用list(string)- 尽管您甚至不需要这样做,因为 Python 字符串是可迭代的,您可以join直接对它们执行 a 操作,就像您对 Python 列表执行操作一样。(感谢@Blckknght 指出这一点。)在 Ruby 或 JavaScript 中,这string.split('')- 有趣的是,这两种语言的语法是相同的。

然后,您只需获取结果并join(' ')以该语言的适当语法对其进行处理。所有三种语言的代码都非常相似。

红宝石:

def spaced_word( s )
    s.split('').join(' ')
end

JavaScript:

function spacedWord( s ) {
    return s.split('').join(' ');
}

Python:

def spaced_word( s ):
    return ' '.join( s )

或者让它与其他两种语言更相似:

def spaced_word( s ):
    return ' '.join( list(s) )

这提出了一个(希望)有趣的观点。我对 Python 代码的第一种方法是使用显式list(s). 最近我一直在用 JavaScript、Python 和 Ruby 编写代码,但最近一周左右的时间主要是 JavaScript。所以当我写了一点 Python 代码时,我自然而然地陷入了一种更加 JavaScript 风格的做法:先将字符串转换为数组(列表),然后join对其进行调用。在 JavaScript 中,您不能join直接调用字符串。但是在 Python 中你可以!

也许您的代码中发生了类似的事情?仔细逐字符循环编写它的方式是在 C 和其他一些语言中执行它的方式。将编码模式从一种语言转移到另一种语言是一种自然趋势,就像我从 JavaScript 思维方式编写 Python 代码一样。

就我自己而言,我知道我必须不断地与之抗争,并根据我目前正在编码的语言以及它提供的功能进行思考。Python 与 Ruby 和 JavaScript 以及其他类似语言一起,提供了丰富的字符串和数组/列表操作函数,因此在编写您自己的更详细的代码之前,这是可以查看的地方。

于 2013-06-16T03:17:04.967 回答
-1

在内存变量 s

有一个像 'hello' 的值意味着 s='hello'

您将每个字母与空格一起存储在内存变量“t”中

s[i] + ' ' + s[i + 1] + ' '
s[1] = ' ' + s[1 + 1] + ' '
s[1] = ' ' + h        + ' '
s[1] = ' h '    // here you are getting space before & after  s[1 + 1]

所以你的结果就像'你好'

while t = t + s[i + 1] + ' '
gives result 'h e l l o '
于 2013-06-16T03:27:01.303 回答