Как работает str (список)?

почему str(list) возвращает, как мы видим списке на консоли? Как это str(list) работы? (любая ссылка на код CPython для str(list))?

>>> 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']

Is literal_eval аналогично eval? Is 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', "'", ',', ' ', '"', "'", '"', ',', ' ', "'", ',', "'", ',', ' ', "'", ' ', "'", ',', ' ', "'", '"', "'", ',', ' ', '"', "'", '"', ',', ' ', "'", '"', "'", ',', ' ', "'", ',', "'", ',', ' ', "'", ' ', "'", ',', ' ', '"', "'", '"', ',', ' ', "'", ']', "'", ',', ' ', '"', "'", '"', ',', ' ', "'", ']', "'", ']']

3 ответов


Ну у вас есть всего 4 вопроса, давайте по одному.

1. Почему str(list) возвращает, как мы видим list на консоли? Как это str(list) работы?

что это str() и __str__()?

на str() вызывается, чтобы вернуть printable только форма объекта! От docs

str(object) не всегда пытайтесь вернуть строку, которая приемлемо для eval(); его цель-вернуть строку для печати.

на __str__() функция в классе вызывается всякий раз, когда вы вызываете str() на объект. Опять из документация

object.__str__(self)

называют str() встроенная функция и print оператор для вычисления "неформального" строкового представления объект.

что такое list отзывной?

на list() востребуемых является создание списка из повторяемое в качестве аргумента. Опять из docs

возвратить list чьи детали такие же и в таком же заказе как элементы iterable

таким образом, 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() on list('dummy'), вы не получите обратно свою исходную строку 'dummy', так что снова у вас будет использовать join! Таким образом, вспоминая ту же функцию будет не вернуть вам ваш оригинальный объект!

Так str() над списком вызывает builtin __str__() метод списка?

ответ-нет!

что происходит внутри, когда вы называете str() в списке?

всякий раз, когда вы называете str() в объекте списка следующие шаги

  1. вызов repr() каждого элемента списка.
  2. добавить фантазии [ на фронте и еще ] в конце списка.
  3. Присоединяйтесь ко всем с запятой.

как вы можете видеть из кода объекта в список cpython на github. проходя через исходный код cpython в hg.питон, что более ясно, вы можете увидеть после трех комментариев. (спасибо Эшвини за ссылку на этот конкретный код)

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

они соответствуют пунктам, которые я упомянул выше.

безопасное оцените узел выражения или строку, содержащую литерал Python или отображение контейнера

2. Использование строковых функций и builtins

другой обходной путь можно сделать с помощью 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] затем вам нужно будет пройти через разделенный список и обнаружить тип элемента, а затем преобразовать его и добавить преобразованный элемент в окончательный список.

другое место, где это не удается, когда строка сама содержит символы кавычки. Как упоминалось nneonneo на комментарий

на str.split решение очень хрупкое и сломается, если вход содержит, например, строки, содержащие ", ", или туплю, или другие списки ... Гораздо лучше использовать ast.literal_eval потому что это будет иметь дело со всеми тонкостями синтаксиса.

и для вашего последнего вопроса,

4. Прерывается ли код, если вы делаете str(list(str(list)))) снова и опять?

не совсем так. Выход будет расти все дольше и дольше, как каждый раз, когда вы создаете list of a str а затем снова получить его печатную версию. Ограничение-это только ограничение вашей физической машины. (который будет вскоре достигнут, поскольку каждый шаг длина строки умножается на 5.)


вы, похоже, ожидаете, что создание строки из списка является круговым. Это не должно быть; списки не являются презентабельными объектами конечного пользователя, и вы получаете тот же результат, что и repr(listobject); отладочная информация только для разработчиков.

на list() отзывной создает новый список объектов от произвольного итерируемый объект; строки в Python являются повторяемое изготовления отдельных персонажей, когда вы делаете так, list(stringobject) всегда производит список с индивидуальным письмена.

в таком виде list() никогда не будет пытаться интерпретировать строковый аргумент как синтаксис Python; и это даже не сработает, если исходный список содержит объекты без буквенной нотации Python. Возьмем для примера:

>>> def foo(): return 'bar'
... 
>>> alist = [foo]
>>> alist
[<function foo at 0x106c748c0>]

вы не можете взять этот вывод строки отладки и вернуть его в исходный список, особенно если вы запустите его в интерпретаторе Python, где даже не определена такая функция.


на str() функция в python используется для преобразования значения в строку. Простой ответ на то, что str() с list заключается в том, что она создает строковое представление списка (квадратные скобки и все).

что касается list(str(list)), все, что вы делаете, это говорите python преобразовать исходный список в строку, затем вы разделяете эту строку и помещаете ее в список, чтобы каждый индекс имел один символ. Чтобы вы могли гнездиться list и str вызовы столько раз, сколько вы хотите (при условии, что ваш компьютер имеет достаточно памяти).