как преобразовать список строк в список подсписков отдельных символов в строках?

Итак, я начинаю с:

['BLUE', 'ORANGE', 'YELLOW', 'GREEN', 'BLACK', 'PURPLE', 'BROWN']

и я хочу:

[['B', 'L', 'U', 'E'], ['O', 'R', 'A', 'N', 'G', 'E'], ['Y', 'E', 'L', 'L', 'O', 'W'], ['G', 'R', 'E', 'E', 'N'], ['B','L', 'A', 'C', 'K'], ['P', 'U', 'R', 'P', 'L', 'E'], ['B', 'R', 'O', 'W','N']]

Я попробовал это, потому что казалось, что он будет производить то, что я хотел, но он продолжает говорить мне, что у меня есть ошибка. AttributeError: объект «NoneType» не имеет атрибута «добавить»:

first_list = ['BLUE', 'ORANGE', 'YELLOW', 'GREEN', 'BLACK', 'PURPLE', 'BROWN']
list_1 = []

for i in range (len(first_list)):
    list_1 = list_1.append(list(first_list[i]))

return list_1

У меня по-прежнему возникают проблемы с использованием «.append» и я продолжаю использовать «+» в других итерациях, но это просто дает мне длинный список всех символов вместо списка подсписков символов. Спасибо за любую помощь или совет.


person Israel CA    schedule 02.11.2012    source источник
comment
связаны, если не дублируются stackoverflow.com/questions/113655/   -  person Liviu T.    schedule 03.11.2012


Ответы (7)


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

>>> words = ['BLUE', 'ORANGE', 'YELLOW', 'GREEN', 'BLACK', 'PURPLE', 'BROWN']
>>> [list(word) for word in words]
[['B', 'L', 'U', 'E'], ['O', 'R', 'A', 'N', 'G', 'E'], ['Y', 'E', 'L', 'L', 'O', 'W'], ['G', 'R', 'E', 'E', 'N'], ['B', 'L', 'A', 'C', 'K'], ['P', 'U', 'R', 'P', 'L', 'E'], ['B', 'R', 'O', 'W', 'N']]

Изменить: ошибка атрибута, которую вы получили, связана с тем, что метод append() списка возвращает None. Поскольку вы назначаете вывод метода переменной list1, вы перезаписываете список значением None в первый раз в цикле. Поскольку None не имеет метода append, в следующий раз в цикле вы получите ошибку. Удаление этого назначения заставляет ваш код работать:

>>> first_list = ['BLUE', 'ORANGE', 'YELLOW', 'GREEN', 'BLACK', 'PURPLE', 'BROWN']
>>> list_1 = []
>>> for i in range (len(first_list)):
...     list_1.append(list(first_list[i]))
... 
>>> list_1
[['B', 'L', 'U', 'E'], ['O', 'R', 'A', 'N', 'G', 'E'], ['Y', 'E', 'L', 'L', 'O', 'W'], ['G', 'R', 'E', 'E', 'N'], ['B', 'L', 'A', 'C', 'K'], ['P', 'U', 'R', 'P', 'L', 'E'], ['B', 'R', 'O', 'W', 'N']]
person Blair    schedule 02.11.2012
comment
Это AttributeError, а не SyntaxError. (Все еще +1 за то, что это не только первая рекомендация для понимания списка, но и единственная, которая объяснила, почему ее использовать, и дала ссылку.) - person abarnert; 03.11.2012
comment
Спасибо, что объяснили, в чем была моя ошибка. Спасибо всем за вашу помощь. - person Israel CA; 03.11.2012

>>> map(list,first_list)
[['B', 'L', 'U', 'E'], ['O', 'R', 'A', 'N', 'G', 'E'], ['Y', 'E', 'L', 'L', 'O', 'W'], ['G', 'R', 'E', 'E', 'N'], ['B', 'L', 'A', 'C', 'K'], ['P', 'U', 'R', 'P', 'L', 'E'], ['B', 'R', 'O', 'W', 'N']]

Конструктор list применяется к каждому элементу исходного списка. И элементы исходного списка — это строки, которые являются итерируемыми. Таким образом, list просто использует строку, рассматривая ее как итератор, поэтому в конечном итоге она содержит буквы (поскольку строки дают буквы как элементы, если они повторяются).

person ovgolovin    schedule 02.11.2012

Единственная причина, по которой ваш существующий код не работает, заключается в том, что list.append изменяет список на месте и возвращает None. Так:

for i in range (len(first_list)):
    list_1 = list_1.append(list(first_list[i]))

В первый раз вы добавляете первое слово в list_1, а затем устанавливаете list_1 в None. Так что в следующий раз вы получите AttributeError.

Просто сделайте это:

for i in range (len(first_list)):
    list_1.append(list(first_list[i]))

Или используйте функцию, которая не изменяет список на месте, а вместо этого возвращает новый:

for i in range (len(first_list)):
    list_1 = list_1 + [list(first_list[i])]

Немного глупо перебирать range(len(first_list)), если все, что вам нужно с индексом i, это first_list[i]; вы можете просто перебрать first_list напрямую. (И даже если вам действительно нужен i для других целей, вы можете перебрать enumerate(first_list) в цикле.)

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

На самом деле, одна из многих причин этого заключается в том, что вам не нужно запоминать append против extend, какие функции изменяются, какие возвращают новые значения и так далее.

person abarnert    schedule 02.11.2012

Вы можете просто преобразовать строку в список, чтобы получить список символов строки.

words = ['BLUE', 'ORANGE', 'YELLOW', 'GREEN', 'BLACK', 'PURPLE', 'BROWN']
split_words = [list(word) for word in li]
person Acorn    schedule 02.11.2012
comment
Судя по тому, что он пытался, у него не было проблем с частью list(word), но с объединением всех результатов (тривиальное понимание списка). - person abarnert; 03.11.2012

Это будет делать:

myList = ['BLUE', 'ORANGE', 'YELLOW', 'GREEN', 'BLACK', 'PURPLE', 'BROWN']

res = [[i for i in s] for s in myList]

res
[['B', 'L', 'U', 'E'], ['O', 'R', 'A', 'N', 'G', 'E'], ['Y', 'E', 'L', 'L', 'O', 'W'],    ['G', 'R', 'E', 'E', 'N'], ['B', 'L', 'A', 'C', 'K'], ['P', 'U', 'R', 'P', 'L', 'E'], ['B', 'R', 'O', 'W', 'N']]
person Netwave    schedule 02.11.2012

Вы можете применить list() к каждому элементу, используя map:

>>> words = ['BLUE', 'ORANGE', 'YELLOW', 'GREEN', 'BLACK', 'PURPLE', 'BROWN']
>>> map(list, words)
[['B', 'L', 'U', 'E'], ['O', 'R', 'A', 'N', 'G', 'E'], ['Y', 'E', 'L', 'L', 'O', 'W'], ['G', 'R', 'E', 'E', 'N'], ['B', 'L', 'A', 'C', 'K'], ['P', 'U', 'R', 'P', 'L', 'E'], ['B', 'R', 'O', 'W', 'N']]

Хотя я не уверен, зачем вам это нужно. Строки и списки ведут себя почти одинаково.

person Blender    schedule 02.11.2012

Ваше текущее решение не работает, потому что list.append() возвращает None, а вы присваиваете результат list_1.append() обратно list_1, поэтому на второй итерации вы получаете ошибку атрибута.

Вот как вы можете исправить свой текущий код:

first_list = ['BLUE', 'ORANGE', 'YELLOW', 'GREEN', 'BLACK', 'PURPLE', 'BROWN']
list_1 = []
for i in range(len(first_list)):
    list_1.append(list(first_list[i]))

Лучшим решением было бы напрямую перебирать элементы в списке:

for s in first_list:
    list_1.append(list(s))

Но лучший способ сделать это - использовать понимание списка или карту, как и в других ответах.

person Andrew Clark    schedule 02.11.2012