0

他の 2 つの一般的な文字列を使用して新しい文字列を生成しますが、自分の 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

ここには実際には 2 つの問題があります。

まず、Mike が指摘したように、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 です。では、13 の場合はどうなるnでしょうか。は明らかn < 13 or n < 17に正しいので、次の行に移動してstring1[n].

を に変更して修正できorますand

しかし実際には、そもそも間違いにくいコードを書いたほうがよいのです。

まず、これを行うことができます:

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

次に、 で始まり、 をループしn = 0、をループするループを書くときはいつでも、それを範囲のループとして書き直すことができますし、そうすべきです:whilen < <something>n += 1for

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

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)

3 つのソリューションは同等であり、結果は期待どおりになりました。

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))

あなたのステートメントは、OR で結合された 2 つのものです。つまり、どちらかが true の場合、条件全体が true です。この場合len(string2)は no-0 なので、何nをしていても「真」です。

そして、abarnert が指摘したように、とにかく「or」は正しいチェックではありません。長さが 13 または長さが 17 の場合でも、長さは 13 からオーバーフローします (< 17 のチェックは、len(string2)そのまま続行できるためです)。

最も簡単な解決策は、 を に置き換えるだけだと思いorますand

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

これは、いずれかの文字列の長さ (この場合は短い方の 13) になると実行を停止しnます>=

于 2013-01-25T22:13:23.913 に答える
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 に答える
0

次のように変更する必要がありますn < len(string1) or len(string2)

n < len(string1) or n < len(string2)
于 2013-01-25T22:13:25.560 に答える
-2

string1 は 4 文字 (上限 3) string2 は 6 文字 (上限 5)

ループ条件を修正してもまだ問題がありますループ条件は while n < (4 or 6) です

これは、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 に答える