str(list)如何工作? [英] How does str(list) work?
问题描述
为什么str(list)
返回控制台上的列表显示方式? str(list)
如何工作? (是否引用了str(list)
的CPython代码)?
Why does str(list)
returns how we see list on the console? How does str(list)
work? (any reference to the CPython code for str(list)
)?
>>> x = ['abc', 'def', 'ghi']
>>> str(x)
"['abc', 'def', 'ghi']"
要从str(list)
返回原始列表,我必须:
To get the original list back from the str(list)
I have to:
>>> 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)
转到原始列表?
Why doesn't list(str(list))
turns the str(list)
back to the original list?
或者我可以使用:
>>> eval(str(x))
['abc', 'def', 'ghi']
literal_eval
是否与eval
相同? eval
使用安全吗?
Is literal_eval
the same as eval
? Is eval
safe to use?
我可以执行以下几次?如果继续执行str(list(str(list))))
,代码会中断吗?例如
How many times can I do the following? Does the code break if it keep on doing str(list(str(list))))
? E.g.
>>> 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个问题,让我们一一解答.
Well you have a total of 4 questions, let us go one by one.
1.为什么
str(list)
返回在控制台上看到list
的方式?str(list)
如何工作?
1. Why does
str(list)
returns how we seelist
on the console? How doesstr(list)
work?
什么是 str()
和文档
What is str()
and __str__()
?
The str()
callable is to return a printable form of the object only! From the docs
str(object)
并不总是尝试返回一个字符串,该字符串是eval()
可接受的;它的目标是返回可打印的字符串.
str(object)
does not always attempt to return a string that is acceptable toeval()
; its goal is to return a printable string.
每当您在对象上调用str()
时,都会调用类中的__str__()
函数.再次从文档
The __str__()
function in a class is called whenever you call str()
on an object. Again from the documentation
object.__str__(self)
由str()
内置函数和print
语句调用,以计算对象的非正式"字符串表示形式.
Called by the str()
built-in function and by the print
statement to compute the "informal" string representation of an object.
可调用的 list
是什么?
list()
可调用对象是根据作为参数传递的可迭代对象创建列表.再次从文档
What is the list
callable?
The list()
callable is to create a list from an iterable passed as an argument. Again from the docs
返回与项目相同且顺序相同的
list
可迭代的项目
Return a
list
whose items are the same and in the same order as iterable‘s items
因此,str(list)
为您提供了可打印的形式,并且list(str(list))
将遍历字符串.即list(str(list))
将为您提供所传递参数的可打印形式的各个字符的列表.
Thus, str(list)
gives you a printable form and list(str(list))
will iterate over the string. That is list(str(list))
will give you a list of the individual characters of the printable form of the argument passed.
嵌套调用之间的一小步操作,
A small walk-through between the nested calls,
列表,l = ['a','b']
(为您举一个比您的问题小的例子而道歉的人).
调用str(l)
时,它将返回列表l
的可打印形式,即"['a','b']"
.
When you call str(l)
, it returns a printable form of the list l
, that is "['a','b']"
.
现在您可以清楚地看到"['a','b']"
是一个字符串,并且确实是一个 iterable .现在,当您在此调用list
时,即list("['a','b']")
,您会得到一个奇怪的列表,例如['[', "'", 'a', "'", ',', "'", 'b', "'", ']']
. 为什么会这样?之所以会这样,是因为字符串会反复遍历其字符,因此您可以使用虚拟字符串进行测试,
Now you can see clearly that "['a','b']"
is a string and is indeed an iterable. Now when you call list
on this i.e. list("['a','b']")
you get a weird list like ['[', "'", 'a', "'", ',', "'", 'b', "'", ']']
. Why does this happen? This happens because the string iterates over its characters, you can test this by using a dummy string,
>>> 'dummy'
'dummy'
>>> list('dummy')
['d', 'u', 'm', 'm', 'y']
因此,当您在字符串上调用list
时,将获得一个字符列表.请再次注意,在这里,当您在list('dummy')
上调用str()
时,您将不会取回原始字符串'dummy'
,因此,您将不得不再次使用
Thus when you call the list
on a string you get a list of character. Note that again here, when you call str()
on list('dummy')
, you will not get back your original string 'dummy'
, so again you will have to use join
! Thus recalling the same function will NOT get you back your original object!
那么,通过列表调用str()
会调用列表的内置__str__()
方法吗?
So, Calling str()
over a list calls the builtin __str__()
method of the list?
答案是否定的!
The answer is NO!
每当您在列表对象上调用str()
时,遵循的步骤就是
Whenever you call str()
on an list object, the steps followed are
- 调用每个列表元素的
repr()
. - 在列表的前面添加一个精美的
[
,在列表的末尾添加另一个]
. - 用逗号加入所有的人.
- Call the
repr()
of each of the list element. - Add a fancy
[
at the front and another]
at the end of the list. - Join all of them with a comma.
从 hg.python ,这更加清楚,您可以看到以下三个注释. (感谢Ashwini提供该特定代码的链接) >
As you can see from the source code of the list object in cpython on github. Going through the source code of cpython in hg.python, which is more clear, you can see the following three comments. (Thanks to Ashwini for the link on that particular code)
/* 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)
这些与我上面提到的要点相对应.
These correspond to the points I mentioned above.
repr()
打印所有对象的字符串表示形式.再次从文档
repr()
prints the string representation of all the objects. Again from the documentation
返回一个包含对象可打印表示形式的字符串.
Return a string containing a printable representation of an object.
还要注意这句话!
对于许多类型,此函数都会尝试返回一个字符串 传递给
eval()
时将产生具有相同值的对象, 否则,表示形式是用尖括号括起来的字符串 包含对象类型的名称以及 附加信息通常包括名称和地址 对象.
For many types, this function makes an attempt to return a string that would yield an object with the same value when passed to
eval()
, otherwise the representation is a string enclosed in angle brackets that contains the name of the type of the object together with additional information often including the name and address of the object.
现在是您的第二个问题,
And now your second question here,
2.
list(str(list))
为什么不将str(list)
变回原始列表?
2. Why doesn't
list(str(list))
turns thestr(list)
back to the original list?
在内部,str(list)
实际上创建列表对象的repr()
表示形式.因此,要在调用列表中的str
之后返回列表,您实际上需要执行 eval
,而不是list
调用.
Internally, str(list)
actually creates the repr()
representation of the list object. So to get back the list after calling str
on the list, you actually need to do eval
on it and not a list
call.
但是我们都知道 eval
是邪恶 ,那么解决方法是什么?
But we all know that eval
is evil, so what is/are the workaround(s)?
第一个解决方法是使用 ast.literal_eval
一个>.这使我们想到了您的第三个问题,
The first work-around would be to use ast.literal_eval
. That brings us to your 3rd question,
3.
literal_eval()
与eval()
相同吗?eval()
使用安全吗?
3. Is
literal_eval()
the same aseval()
? Iseval()
safe to use?
ast.literal_eval()
是安全的
ast.literal_eval()
is safe unlike the eval()
function. The docs themselves mention that it is safe --
安全评估表达式节点或包含Python文字或容器显示内容的字符串
Safely evaluate an expression node or a string containing a Python literal or container display
2.使用字符串函数和内建函数
可以使用 str.split()
>>> x = ['abc', 'def', 'ghi']
>>> a = str(x)
>>> a[2:-2].split("', '")
['abc', 'def', 'ghi']
这只是对字符串列表执行此操作的一种简单方法.有关整数列表,您将需要 map
.
This is just a simple way to do that for a list of strings. For a list of integers you will need 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]
一样是异构的,那么您将不得不遍历拆分列表并发现元素类型,然后将其转换并将转换后的元素附加到最终列表中.
Thus unlike literal_eval
these are simple hacks given that you know the elements of the list. If they are heterogeneous in nature like [1, "a", True]
then you will have to loop through the split list and discover the element type and then convert it and append the converted element to a final list.
另一个失败的地方是字符串本身包含引号字符.如 nneonneo 在
Another place where this fails is when the string itself contains quote characters. As mentioned by nneonneo in a comment
str.split
解决方案非常脆弱,如果输入中包含例如包含", "
或元组或其他列表的字符串,...最好使用ast.literal_eval
,因为这将处理语法的所有细微问题.
The
str.split
solution is very fragile and will break if the input contains e.g. strings that contain", "
, or tuples, or other lists, ... It is much better to useast.literal_eval
because that will deal with all the subtleties of the syntax.
最后一个问题,
4.如果一次又一次地
str(list(str(list))))
,代码会中断吗?
4. Does the code break if you do
str(list(str(list))))
again and again?
并非如此.每次创建str
的list
然后再次获得其可打印版本时,输出将越来越长.该限制仅是您的物理机的限制. (每步将字符串长度乘以5就会很快达到).
Not really. The output will grow longer and longer as each time you are creating a list
of a str
and then again getting the printable version of it. The limitation is your physical machine's limitation only. (which will be soon reached as each step the string length is multiplied by 5.)
这篇关于str(list)如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!