なぜ'?\\\?'=='?\\\\?'与えるのTrueか教えてもらえますか?それは私を夢中にさせ、私は合理的な答えを見つけることができません...
>>> list('?\\\?')
['?', '\\', '\\', '?']
>>> list('?\\\\?')
['?', '\\', '\\', '?']
なぜ'?\\\?'=='?\\\\?'与えるのTrueか教えてもらえますか?それは私を夢中にさせ、私は合理的な答えを見つけることができません...
>>> list('?\\\?')
['?', '\\', '\\', '?']
>>> list('?\\\\?')
['?', '\\', '\\', '?']
list():>>> '?\\\?' '?\\\\?'
回答:
基本的に、Pythonはバックスラッシュ処理に少し寛容だからです。https://docs.python.org/2.0/ref/strings.htmlからの引用:
標準Cとは異なり、認識されないすべてのエスケープシーケンスは変更されずに文字列に残ります。つまり、バックスラッシュは文字列に残ります。
(オリジナルの強調)
したがって、Pythonでは、3つのバックスラッシュが4に等しいということではありません。バックスラッシュの後にのような文字を続けると、認識されたエスケープシーケンスではない?ため、2つが2つの文字として結合\?されます。
'escape''d')として機能します。そこで他のキャラクターを覚える必要もありません!
これは、組み合わせが有効なエスケープシーケンスを表す場合、バックスラッシュが直後の文字のエスケープ文字として機能するためです。ダースほどのエスケープシーケンスがここにリストされています。それらには、改行\n、水平タブ\t、キャリッジリターンなどの明白なものや、たとえばUnicode文字を表す\r名前付きUnicode文字などのあいまいなものが含まれます。ただし、重要な点は、エスケープシーケンスが不明な場合、文字シーケンスはそのまま文字列に残るということです。\N{...}\N{WAVY DASH}\u3030
問題の一部は、Pythonインタープリターの出力が誤解を招く可能性もあります。これは、表示時に円記号がエスケープされるためです。ただし、これらの文字列を印刷すると、余分なバックスラッシュが消えます。
>>> '?\\\?'
'?\\\\?'
>>> print('?\\\?')
?\\?
>>> '?\\\?' == '?\\?' # I don't know why you think this is True???
False
>>> '?\\\?' == r'?\\?' # but if you use a raw string for '?\\?'
True
>>> '?\\\\?' == '?\\\?' # this is the same string... see below
True
特定の例の場合'?\\\?'、最初のケースでは、最初の\バックスラッシュは1つのバックスラッシュを残して2番目のバックスラッシュをエスケープしますが、3番目のバックスラッシュは\?有効なエスケープシーケンスではないため、バックスラッシュのままです。したがって、結果の文字列は?\\?です。
2番目のケース'?\\\\?'では、最初のバックスラッシュは2番目をエスケープし、3番目のバックスラッシュは4番目をエスケープして、文字列になります?\\?。
したがって、3つのバックスラッシュは4つと同じです。
>>> '?\\\?' == '?\\\\?'
True
3つの円記号を含む文字列を作成する場合は、各円記号をエスケープできます。
>>> '?\\\\\\?'
'?\\\\\\?'
>>> print('?\\\\\\?')
?\\\?
または、「生の」文字列の方がわかりやすいかもしれません。
>>> r'?\\\?'
'?\\\\\\?'
>>> print(r'?\\\?')
?\\\?
文字列リテラルのエスケープシーケンス処理が終了します。詳細については、文字列リテラルを参照してください。
'?\\\?'=='?\\?'ますFalse、私はそれをタイプミスしました。それは'?\\\?'=='?\\\\?'質問が示すように、私はそれを修正しました。
https://docs.python.org/2/reference/lexical_analysis.htmlの文字列リテラルの下のpython字句解析ページから
認識されたすべてのエスケープシーケンスをリストする表があります。
\\は、=== \であるエスケープシーケンスです。
\?エスケープシーケンスではなく、=== \?
したがって、「\\\\」は「\\」の後に「\\」が続く「\\」(2つのエスケープされた\)
そして '\\\'は '\\'の後に '\'が続き、これも '\\'です(1つはエスケープされ、もう1つは生の\)
また、Pythonは他の一部の言語とは異なり、文字列リテラルを囲む単一引用符と二重引用符を区別しないことに注意してください。
したがって、「文字列」と「文字列」はPythonではまったく同じものであり、エスケープシーケンスの解釈には影響しません。
mhawkeの答えはそれをかなりカバーしています、私はもっと簡潔な形で、そしてこの振る舞いを説明する最小限の例でそれを言い直したいだけです。
追加すべきことの1つは、エスケープ処理が左から右に移動するため、\n最初にバックスラッシュを見つけてから、エスケープする文字を探し、次にそれを見つけnてエスケープすることです。\\n最初のバックスラッシュを見つけ、2番目を見つけてエスケープし、次にそれをnリテラルnとして見つけて見ます。\?バックスラッシュを見つけてエスケープする文字を探し、エスケープ?できない文字を見つけ\て、文字どおりのバックスラッシュとして扱います。
mhawkeが指摘したように、ここで重要なのは、対話型インタープリターが文字列を表示するときにバックスラッシュをエスケープすることです。その理由は、インタープリターからコードエディターにコピーされたテキスト文字列が有効なPython文字列であることを確認するためだと思います。ただし、この場合、便宜上のこの手当は混乱を引き起こします。
>>> print('\?') # \? is not a valid escape code so backslash is left as-is
\?
>>> print('\\?') # \\ is a valid escape code, resulting in a single backslash
'\?'
>>> '\?' # same as first example except that interactive interpreter escapes the backslash
\\?
>>> '\\?' # same as second example, backslash is again escaped
\\?