str(list)
がコンソールにリストを表示する方法を返すのはなぜですか?str(list)
はどのように機能しますか?(str(list)
のCPythonコードへの参照)?
_>>> x = ['abc', 'def', 'ghi']
>>> str(x)
"['abc', 'def', 'ghi']"
_
str(list)
から元のリストを取得するには、次のようにする必要があります。
_>>> from ast import literal_eval
>>> x = ['abc', 'def', 'ghi']
>>> str(x)
"['abc', 'def', 'ghi']"
>>> list(str(x))
['[', "'", 'a', 'b', 'c', "'", ',', ' ', "'", 'd', 'e', 'f', "'", ',', ' ', "'", 'g', 'h', 'i', "'", ']']
>>> literal_eval(str(x))
['abc', 'def', 'ghi']
_
なぜlist(str(list))
はstr(list)
を元のリストに戻さないのですか?
または私は使うことができます:
_>>> eval(str(x))
['abc', 'def', 'ghi']
_
_literal_eval
_はeval
と同じですか?eval
を使用しても安全ですか?
次の操作を何回実行できますか?str(list(str(list))))
?を実行し続けると、コードは壊れますか?例:.
_>>> x = 'abc'
>>> list(x)
['a', 'b', 'c']
>>> str(list(x))
"['a', 'b', 'c']"
>>> list(str(list(x)))
['[', "'", 'a', "'", ',', ' ', "'", 'b', "'", ',', ' ', "'", 'c', "'", ']']
>>> str(list(str(list(x))))
'[\'[\', "\'", \'a\', "\'", \',\', \' \', "\'", \'b\', "\'", \',\', \' \', "\'", \'c\', "\'", \']\']'
>>> list(str(list(str(list(x)))))
['[', "'", '[', "'", ',', ' ', '"', "'", '"', ',', ' ', "'", 'a', "'", ',', ' ', '"', "'", '"', ',', ' ', "'", ',', "'", ',', ' ', "'", ' ', "'", ',', ' ', '"', "'", '"', ',', ' ', "'", 'b', "'", ',', ' ', '"', "'", '"', ',', ' ', "'", ',', "'", ',', ' ', "'", ' ', "'", ',', ' ', '"', "'", '"', ',', ' ', "'", 'c', "'", ',', ' ', '"', "'", '"', ',', ' ', "'", ']', "'", ']']
>>> str(list(str(list(str(list(x))))))
'[\'[\', "\'", \'[\', "\'", \',\', \' \', \'"\', "\'", \'"\', \',\', \' \', "\'", \'a\', "\'", \',\', \' \', \'"\', "\'", \'"\', \',\', \' \', "\'", \',\', "\'", \',\', \' \', "\'", \' \', "\'", \',\', \' \', \'"\', "\'", \'"\', \',\', \' \', "\'", \'b\', "\'", \',\', \' \', \'"\', "\'", \'"\', \',\', \' \', "\'", \',\', "\'", \',\', \' \', "\'", \' \', "\'", \',\', \' \', \'"\', "\'", \'"\', \',\', \' \', "\'", \'c\', "\'", \',\', \' \', \'"\', "\'", \'"\', \',\', \' \', "\'", \']\', "\'", \']\']'
>>> list(str(list(str(list(str(list(x)))))))
['[', "'", '[', "'", ',', ' ', '"', "'", '"', ',', ' ', "'", '[', "'", ',', ' ', '"', "'", '"', ',', ' ', "'", ',', "'", ',', ' ', "'", ' ', "'", ',', ' ', "'", '"', "'", ',', ' ', '"', "'", '"', ',', ' ', "'", '"', "'", ',', ' ', "'", ',', "'", ',', ' ', "'", ' ', "'", ',', ' ', '"', "'", '"', ',', ' ', "'", 'a', "'", ',', ' ', '"', "'", '"', ',', ' ', "'", ',', "'", ',', ' ', "'", ' ', "'", ',', ' ', "'", '"', "'", ',', ' ', '"', "'", '"', ',', ' ', "'", '"', "'", ',', ' ', "'", ',', "'", ',', ' ', "'", ' ', "'", ',', ' ', '"', "'", '"', ',', ' ', "'", ',', "'", ',', ' ', '"', "'", '"', ',', ' ', "'", ',', "'", ',', ' ', "'", ' ', "'", ',', ' ', '"', "'", '"', ',', ' ', "'", ' ', "'", ',', ' ', '"', "'", '"', ',', ' ', "'", ',', "'", ',', ' ', "'", ' ', "'", ',', ' ', "'", '"', "'", ',', ' ', '"', "'", '"', ',', ' ', "'", '"', "'", ',', ' ', "'", ',', "'", ',', ' ', "'", ' ', "'", ',', ' ', '"', "'", '"', ',', ' ', "'", 'b', "'", ',', ' ', '"', "'", '"', ',', ' ', "'", ',', "'", ',', ' ', "'", ' ', "'", ',', ' ', "'", '"', "'", ',', ' ', '"', "'", '"', ',', ' ', "'", '"', "'", ',', ' ', "'", ',', "'", ',', ' ', "'", ' ', "'", ',', ' ', '"', "'", '"', ',', ' ', "'", ',', "'", ',', ' ', '"', "'", '"', ',', ' ', "'", ',', "'", ',', ' ', "'", ' ', "'", ',', ' ', '"', "'", '"', ',', ' ', "'", ' ', "'", ',', ' ', '"', "'", '"', ',', ' ', "'", ',', "'", ',', ' ', "'", ' ', "'", ',', ' ', "'", '"', "'", ',', ' ', '"', "'", '"', ',', ' ', "'", '"', "'", ',', ' ', "'", ',', "'", ',', ' ', "'", ' ', "'", ',', ' ', '"', "'", '"', ',', ' ', "'", 'c', "'", ',', ' ', '"', "'", '"', ',', ' ', "'", ',', "'", ',', ' ', "'", ' ', "'", ',', ' ', "'", '"', "'", ',', ' ', '"', "'", '"', ',', ' ', "'", '"', "'", ',', ' ', "'", ',', "'", ',', ' ', "'", ' ', "'", ',', ' ', '"', "'", '"', ',', ' ', "'", ']', "'", ',', ' ', '"', "'", '"', ',', ' ', "'", ']', "'", ']']
_
さて、あなたは全部で4つの質問があります。
1。
str(list)
が、list
がコンソールにどのように表示されるかを返すのはなぜですか?str(list)
はどのように機能しますか?
str()
および __str__()
とは何ですか?str()
呼び出し可能オブジェクトは、オブジェクトのprintable形式のみを返します! docs から
str(object)
は、常にeval()
で受け入れ可能な文字列を返そうとするわけではありません。その目的は、印刷可能な文字列を返すことです。
オブジェクトの__str__()
を呼び出すと、クラスのstr()
関数が呼び出されます。再び documentation から
object.__str__(self)
str()
組み込み関数および
list
呼び出し可能とは何ですか?list()
呼び出し可能オブジェクトは、引数として渡された反復可能オブジェクトからリストを作成します。再び docs から
Iterableのアイテムと同じ、同じ順序のアイテムである
list
を返します
したがって、str(list)
は印刷可能なフォームを提供し、list(str(list))
は文字列を反復処理します。つまり、list(str(list))
は、渡された引数の印刷可能な形式の個々の文字のリストを提供します。
ネストされた呼び出し間の小さなウォークスルー、
与えられたリスト、_l = ['a','b']
_ (あなたの質問のそれよりも小さな例を取ることについての謝罪)。
str(l)
を呼び出すと、リストl
の印刷可能な形式、つまり_"['a','b']"
_が返されます。
これで、_"['a','b']"
_が文字列であり、実際にiterableであることがはっきりとわかります。これでlist
を呼び出すと、つまりlist("['a','b']")
になると、_['[', "'", 'a', "'", ',', "'", 'b', "'", ']']
_のような奇妙なリストが表示されます。 なぜこれが起こるのですか?これは、文字列がその文字を反復処理するために発生します。ダミー文字列を使用してこれをテストできます。
_>>> 'dummy'
'dummy'
>>> list('dummy')
['d', 'u', 'm', 'm', 'y']
_
したがって、文字列でlist
を呼び出すと、文字のリストが表示されます。ここでも、str()
でlist('dummy')
を呼び出すと、元の文字列_'dummy'
_が返されないため、再び join
を使用する必要があります。 !このため、同じ関数を呼び出すと[〜#〜](〜#〜]で元のオブジェクトに戻せません!
そのため、リストに対してstr()
を呼び出すと、リストの組み込み__str__()
メソッドが呼び出されますか?
答えはノーです!
str()
を呼び出すと、内部で何が起こりますか?リストオブジェクトでstr()
を呼び出すと、必ず次の手順が実行されます。
repr()
を呼び出します。[
_を追加し、リストの最後に別の_]
_を追加します。cpython on github のリストオブジェクトのソースコードからわかるように、. より明確な hg.python でcpythonのソースコードを確認すると、次の3つのコメントが表示されます。 (その特定の code のリンクについてはAshwiniに感謝します)
_/* Do repr() on each element. Note that this may mutate the list, so must refetch the list size on each iteration. */ line (382) /* Add "[]" decorations to the first and last items. */ line (398) /* Paste them all together with ", " between. */ line (418)
_
これらは、私が前述した点に対応しています。
repr()
とは何ですか?repr()
は、すべてのオブジェクトの文字列表現を出力します。再び documentation から
オブジェクトの印刷可能な表現を含む文字列を返します。
この文章にも注意してください!
多くのタイプの場合、この関数は
eval()
に渡されたときに同じ値のオブジェクトを生成する文字列を返そうとします。それ以外の場合、表現はタイプの名前を含む山括弧で囲まれた文字列です多くの場合、オブジェクトの名前とアドレスを含む追加情報と一緒にオブジェクトの。
そして、ここであなたの2番目の質問、
2。
list(str(list))
がstr(list)
を元のリストに戻さないのはなぜですか?
内部的には、str(list)
は実際にはリストオブジェクトのrepr()
表現を作成します。したがって、リストでstr
を呼び出した後にリストを取得するには、実際にはeval
呼び出しではなく list
を実行する必要があります。
しかし、 eval
はevil であることは誰もが知っているので、回避策は何ですか?
literal_eval
_ を使用する最初の回避策は _ast.literal_eval
_ を使用することです。これで3番目の質問に進みます。
3。
literal_eval()
はeval()
と同じですか?eval()
を使用しても安全ですか?
ast.literal_eval()
安全です 違うeval()
関数。ドキュメント自体は安全だと述べています-
安全にPythonリテラルまたはコンテナの表示を含む式ノードまたは文字列を評価します
str.split()
を使用して別の回避策を実行できます
_>>> x = ['abc', 'def', 'ghi']
>>> a = str(x)
>>> a[2:-2].split("', '")
['abc', 'def', 'ghi']
_
これは、文字列のリストに対してこれを行う簡単な方法です。整数のリストには、 map
が必要です。
_>>> x = [1,2,3]
>>> a =str(x)
>>> list(map(int,a[1:-1].split(', '))) # No need for list call in Py2
[1, 2, 3]
_
したがって、_literal_eval
_とは異なり、リストの要素がわかっている場合、これらは単純なハックです。それらが_[1, "a", True]
_のように本質的に異種である場合、分割リストをループして要素タイプを検出し、それを変換して、変換された要素を最終リストに追加する必要があります。
これが失敗するもう1つの場所は、文字列自体に引用文字が含まれている場合です。 nneonneo で言及されているように comment で
_
str.split
_ソリューションは非常に壊れやすく、入力にたとえば_", "
_を含む文字列、またはタプル、または他のリスト、... _ast.literal_eval
_を使用する方がはるかに優れています。
そして最後の質問ですが
4。
str(list(str(list))))
を何度も実行すると、コードは壊れますか?
あんまり。 list
のstr
を作成し、その印刷可能なバージョンを再び取得するたびに、出力はますます長くなります。制限は、物理マシンの制限のみです。 (各ステップで文字列の長さが5倍されるとすぐに到達します。)
あなたは、リストから文字列を作成することが往復可能であるという期待を持っているように見えます。それは意図されていません。リストはエンドユーザーが提示できるオブジェクトではなく、repr(listobject)
と同じ出力が得られます。開発者の消費に関するデバッグ情報のみ。
list()
呼び出し可能オブジェクトは、任意の反復可能なオブジェクトから新しいリストオブジェクトを作成します。 Python文字列は反復可能であり、個別の文字を生成する場合、list(stringobject)
は常に個別の文字を含むリストを生成します。
そのため、list()
は、文字列引数をPython構文として解釈しようとはしません。元のリストにPythonリテラル表記。例を見てみましょう:
>>> def foo(): return 'bar'
...
>>> alist = [foo]
>>> alist
[<function foo at 0x106c748c0>]
特にPythonインタープリターでこのような関数が定義されていないところでこれを実行する場合、そのデバッグ文字列出力を元のリストに戻すことはできません。
python=のstr()
関数は、値を文字列に変換するために使用されます。str()
がlist
は、リストの文字列表現(角括弧とすべて)を作成することです。
list(str(list))
に関しては、pythonに元のリストを文字列に変換するように指示しているだけで、その文字列を分割してリストに入れ、インデックスは1文字であるため、list
とstr
の呼び出しを必要なだけネストすることができます(コンピュータに十分なメモリがある場合)。