Нужно немного пояснить метод string join ()

Как ни глупо, как это могло бы звучать, попробовал все, и он не сработал и, наконец, перезапустил VS2012, чтобы увидеть, как он снова работает.

0
задан SonOfRoyHodgson 15 January 2019 в 16:38
поделиться

5 ответов

Как указал Мадхан в своем ответе, вы пытаетесь использовать список в качестве первого индекса, а не строку.

Взято из pydocs:

str.join (итерируемый) Возвращает строку, которая является конкатенацией строк в итерируемой. Ошибка TypeError будет возникать, если в итерируемых есть какие-либо нестроковые значения, включая байтовые объекты. Разделителем между элементами является строка, обеспечивающая этот метод.

Таким образом, вам нужно предоставить только строки в вашей итерации. Но если вы видите свой код, вы используете список объектов нескольких типов.

Первый индекс представляет собой список, а другие индексы являются строками.

Вот что происходит:

your_param = [plist[1:3], plist[5], plist[4], plist[7], plist[6]]

type(your_param)
<class 'list'>

for param in your_param:
    type(param)

<class 'list'> # <--- HERE
<class 'str'>
<class 'str'>
<class 'str'>
<class 'str'>

Если вы хотите, чтобы все в одной строке, вы можете сделать что-то вроде:

your_param = [''.join(plist[1:3]), plist[5], plist[4], plist[7], plist[6]]

for param in your_param:
    type(param)

<class 'str'>
<class 'str'>
<class 'str'>
<class 'str'>
<class 'str'>
0
ответ дан Rafael Marques 15 January 2019 в 16:38
поделиться

Вы были , поэтому близки к вашей первоначальной реализации. Я не знаю, введена ли в вашей книге нотация * (звездочка), но вы можете передать каждый элемент в итерируемом с *my_iter

примерно так: my_function(*my_iter)

или просто поместите его в кортеж: (val_a, val_b, val_c, *val_iter)

быстрый пример:

my_list = [1,2,3,4]
my_tuple = (5,6,7,8)

combined_list = [*my_list, *my_tuple]
print(combined_list)

[1, 2, 3, 4, 5, 6, 7, 8] [1112 ]

Теперь вернемся к вашему вопросу: используя обозначение *, мы можем легко решить вашу проблему со звездочкой, чтобы ваш список строк передавался элемент за элементом в ''.join():

phrase = "Don't panic!"
plist = list(phrase)
new_phrase = ''.join([*plist[1:3], plist[5], plist[4], plist[7], plist[6]])
print(new_phrase)

на кране

0
ответ дан David Culbreth 15 January 2019 в 16:38
поделиться

Давайте сначала обсудим правильный ответ. Здесь вы присоединяетесь к plist [1: 3] и создаете строковый объект, затем сохраняете его в new_phrase. Имейте в виду, что теперь это строка. Затем вы добавляете эту строку в другую строку (которая создается другой функцией соединения), поэтому нет ошибки, поскольку вы можете добавить строку в строку.

Возвращаясь к вашему решению, прежде всего, plist [1: 3] - это список, а не строка, поэтому вы не можете использовать его внутри функции соединения, так как она ожидает список, а не список списка.

Таким образом, вы можете сделать plist [1: 3] для строки

new_phrase = ''.join([''.join(plist[1:3]), plist[5], plist[4], plist[7], plist[6]])

, что эквивалентно правильному коду, как вы можете видеть.

0
ответ дан Alok Dixit 15 January 2019 в 16:38
поделиться

Вы создаете plist, используя

plist = list(phrase)

Это означает, что plist является list из str экземпляров, по одному на каждый символ в исходной строке phrase:

>>> plist
['D', 'o', 'n', "'", 't', ' ', 'p', 'a', 'n', 'i', 'c', '!']

Нарезка списка дает другой список, поэтому plist[1:3] это список:

>>> type(plist)
<class 'list'>
>>> type(plist[0])
<class 'str'>
>>> type(plist[0:1])
<class 'list'>

Таким образом, аргумент, который вы передаете в join, содержит как str объекты, так и [ 1112] объект (список, созданный срезанием plist):

>>> [plist[1:3], plist[5], plist[4], plist[7], plist[6]]
[['o', 'n'], ' ', 't', 'a', 'p']

>>> [type(x) for x in [plist[1:3], plist[5], plist[4], plist[7], plist[6]]]
[<class 'list'>, <class 'str'>, <class 'str'>, <class 'str'>, <class 'str'>]

Не имеет значения, что сам внутренний список содержит str объектов, поскольку join не проверяет этот [ 1116] объект. Как только он видит что-то внутри итерируемой вами пропущенной вещи, которая не является str, он поднимает TypeError, который вы видите.

0
ответ дан Daniel Pryden 15 January 2019 в 16:38
поделиться

Вы смешиваете списки и строки внутри другого списка, смешивая нарезку и индексацию. При нарезке создается список, индексирующий отдельный элемент.

Таким образом, рабочий код помещает только отдельных значений в список:

[plist[5], plist[4], plist[7], plist[6]]

, в то время как ваш код также использует нарезку:

[plist[1:3], plist[5], plist[4], plist[7], plist[6]]
#     ^^^^^

, так что теперь вы Первый элемент - это список из 2 элементов.

str.join() могут только соединять строки, поэтому все элементы должны быть строками, любые другие типы объектов (например, список) приводят к ошибкам.

Код в книге работает вокруг этого, соединяя результат среза отдельно:

new_phrase = ''.join(plist[1:3])

Это берет нарезанный список, передавая его str.join() напрямую (не как элемент другого списка). Затем код в книге добавляет результат второго вызова str.join() к следующему:

new_phrase = new_phrase + ''.join([plist[5], plist[4], plist[7], plist[6]])

Современный Python (3.5 или новее) имеет синтаксис для перемещения элементов из [ 1121] список в список, который вы создаете с помощью синтаксиса [...], добавляя элемент к *; это приводит к тому, что все элементы вынимаются и помещаются в текущий список. Вы также можете использовать это здесь, чтобы вынуть все нарезанные строки из среза в новый список:

''.join([*plist[1:3], plist[5], plist[4], plist[7], plist[6]])
#        ^ note the * here, meaning: take all elements from plist[1:3], not plist[1:3] itself.

Это будет зависеть от возраста книги, которую вы используете, будет ли она ввести этот синтаксис.

Всегда полезно посмотреть, что происходит с компонентными элементами выражений Python, в интерактивном интерпретаторе. Вот что происходит с вашим кодом:

>>> phrase = "Don't panic!"
>>> plist = list(phrase)
>>> plist
['D', 'o', 'n', "'", 't', ' ', 'p', 'a', 'n', 'i', 'c', '!']
>>> [plist[1:3], plist[5], plist[4], plist[7], plist[6]]
[['o', 'n'], ' ', 't', 'a', 'p']

Видите этот элемент ['o', 'n'] в начале? Это не одно строковое значение, поэтому str.join() не примет его:

>>> ''.join([plist[1:3], plist[5], plist[4], plist[7], plist[6]])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: sequence item 0: expected str instance, list found

, но если вы проигнорировали эту часть, остаток можно объединить:

>>> ''.join([plist[5], plist[4], plist[7], plist[6]])
' tap'

Если мы используем Синтаксис *, вы получаете плоский список, и ''.join(...) принимает, что:

>>> ''.join([*plist[1:3], plist[5], plist[4], plist[7], plist[6]])
'on tap'
0
ответ дан Martijn Pieters 15 January 2019 в 16:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: