0

通过其他两个常见字符串生成一个新字符串,但我自己的 Python 代码有问题。代码是:

string1 = "doesnt matter"
string2 = "doesnt matter too"
listt = []
n = 0
while n < len(string1) or len(string2):
    if string1[n] in string2:
        listt.append(string1[n])
    n += 1

当我运行代码时,我收到此错误:

Traceback (most recent call last):
  File "<pyshell#121>", line 2, in <module>
    if string1[n] in string2:
IndexError: string index out of range

我不知道为什么字符串索引超出范围,如果n = 0和字符串大于0。

提前致谢,

@viddhart4d8

4

6 回答 6

2

这里实际上有两个问题。

首先,正如迈克所指出的,n < len(string1) or len(string2)相当于(n < len(string)) or len(string2). 换句话说,只要len(string2)不为零,这将始终为真。要解决此问题,请将其更改为n < len(string1) or n < len(string2).

但是当你解决这个问题时,什么都不会改变;你仍然会得到一个IndexError. 这里的问题是,你不仅没有正确地实现你的逻辑,而且逻辑首先是错误的。len(string1)是 13,len(string2)是 17。那么,当n13 时会发生什么?嗯,n < 13 or n < 17显然是真的,所以你仍然要点击下一行并尝试做string1[n].

您可以将其更改or为 anand来解决此问题。

但实际上,最好编写一开始就更难出错的代码。

首先,您可以这样做:

while n < min(len(string1), len(string2)):

其次,每当你编写一个以 开头的循环,在 上n = 0执行一个while循环n < <something>,然后在执行一个n += 1时,你可以并且应该将它重写为for一个范围上的循环:

for n in range(min(len(string1), len(string2))):

同时,如果您考虑一下,我认为如果string2短于string1. 所以真的,你想要的是:

for n in range(len(string1)):

每当你发现自己在循环range(len(<something>)),然后在<something[n]>循环内做,你真的只想<something>直接循环:

for ch in string1:

让我们把它放在一起:

string1 = "doesnt matter"
string2 = "doesnt matter too"
listt = []
for ch in string1:
    if ch in string2:
        listt.append(ch)

这更具可读性——更重要的是,对于新手来说,更难出错。即使是有经验的程序员也经常<在他们应该使用的时候使用<=,或者在复杂的if语句中弄错括号等。但是如果你一开始就不必编写那个逻辑,你就不会犯那些错误。

事实上,你可以更进一步,因为这种模式正是列表推导所做的(或者,filter函数),所以:

string1 = "doesnt matter"
string2 = "doesnt matter too"
listt = [ch for ch in string1 if ch in string2]

但在这一点上,我们并没有消除出错的机会。

于 2013-01-25T23:33:44.397 回答
1

试试这个,使用列表理解

string1 = "doesnt matter"
string2 = "doesnt matter too"
listt = [x for x in string1 if x in string2]

上面的代码更简单,避免了在手动循环输入字符串时需要处理索引等——事实上,这是在 Python 中解决问题的首选方式。

或者,如果您想显式使用循环,这是您的代码的固定版本 - 特别是,请注意条件只需要使用len(string1),无需询问string2's 长度:

listt = []
n = 0
while n < len(string1):
    if string1[n] in string2:
        listt.append(string1[n])
    n += 1

前面的循环可以像这样更惯用地编写,注意不需要使用索引来迭代列表 - 这就是for 循环的用途:

for x in string1:
    if x in string2:
        listt.append(x)

三种解法是等价的,现在结果如预期:

listt
=> ['d', 'o', 'e', 's', 'n', 't', ' ', 'm', 'a', 't', 't', 'e', 'r']
于 2013-01-25T22:13:15.813 回答
1

我想你想要这个:

while n < len(string1) or n < len(string2):

你正在做的是归结为:

while (n < len(string1)) or (len(string2))

您的陈述是两件事或在一起,这意味着如果其中任何一个为真,那么整个条件为真。在这种情况下len(string2),它是 no-0,因此无论在n做什么,它都是“真实的”。

而且,正如 abarnert 指出的那样,“或”无论如何都不是正确的检查。长度 13 或长度 17 仍然会溢出长度 13(因为 < 17 检查将使您继续前进,就像len(string2)让您继续前进一样)。

我觉得最快的解决方案就是orand.

while (n < len(string1)) and (n < len(string2))

这现在将停止运行一次n>=任一字符串的长度(在本例中较短的 13)

于 2013-01-25T22:13:23.913 回答
0

您需要更改n < len(string1) or len(string2)为:

n < len(string1) or n < len(string2)
于 2013-01-25T22:13:25.560 回答
0

我认为这就是你想要做的:

string1 = "doesnt matter"
string2 = "doesnt matter too"
listt = []
n = 0
while n<len(string1) and n<len(string2):
    if string1[n] in string2:
        listt.append(string1[n])
    n += 1

注意以下之间的区别:

while n<len(string1) and n<len(string2):
                     ^^^ ^^ 

与你所拥有的:

while n<len(string1) or len(string2):
                     ^^

如果你想使用or你需要否定整个共轭以获得:

while not(n>=len(string1) or n>=len(string2)):

我认为这并不容易阅读。你也可以使用一个看起来像这样的 Python 形式:

while all(n<len(s) for s in (string1,string2)):

它以同样可读的方式适用于任意数量的字符串。

于 2013-01-25T23:33:30.223 回答
-2

string1 为 4 个字符(上限 3) string2 为 6 个字符(上限 5)

即使您修复了循环条件,仍然存在问题您的循环条件是 while n < (4 or 6)

这意味着 this 在 n<6 时循环。在某些时候,n 将是 4,5 和 6,所有这些都超出了 string1[n] 的范围索引。我不确定您要在输出方面达到什么目标。也许您正在提取常见字符?C#

string s1="xz";
string s2="xyz";
string combined="";

//loop through s1 letter by letter
for (int i=0; i<len(s1); i++){
     s1[i] represents x when i=0

     //loop through s2
     for (int j=0; j<len(s2); j++){
          //if s1[i] (x when i=0) s2[j] (s2[0]=x s2[1]=y s2[2]=z)

          //if they are equal append them to a string named combined and move to the next s1[i] iteration
          if (s1[i]==s2[j]){
            combined+=s1[i];
            break;
          }
     }
}

组合现在应该是 xz

于 2013-01-25T22:16:47.803 回答