str(list)如何工作? [英] How does str(list) work?

查看:82
本文介绍了str(list)如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么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 see list on the console? How does str(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 to eval(); 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

  1. 调用每个列表元素的repr().
  2. 在列表的前面添加一个精美的[,在列表的末尾添加另一个].
  3. 用逗号加入所有的人.
  1. Call the repr() of each of the list element.
  2. Add a fancy [ at the front and another ] at the end of the list.
  3. Join all of them with a comma.

代码的链接) >

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 the str(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 as eval()? Is eval() 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 use ast.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?

并非如此.每次创建strlist然后再次获得其可打印版本时,输出将越来越长.该限制仅是您的物理机的限制. (每步将字符串长度乘以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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆