2

So I am starting with:

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

and I want:

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

I tried this because it looked like it would produce what I wanted but it keeps telling me I have an error. AttributeError: 'NoneType' object has no attribute 'append':

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

I keep having trouble using the ".append" and keep using "+" in other iterations but that just gives me a long list of all the characters instead of a list of sublists of characters. Thank you for any help or advice.

Filip Roséen - refp
  • 62,493
  • 20
  • 150
  • 196
Israel CA
  • 165
  • 1
  • 2
  • 5
  • related if not duplicate http://stackoverflow.com/questions/113655/is-there-a-function-in-python-to-split-a-word-into-a-list – Liviu T. Nov 02 '12 at 23:33

7 Answers7

11

The built-in list() function creates a list from an iterable object. Since a string is an iterable object, we can pass it to list() to create a list of the individual characters. To do this for each of the words, we can use a list comprehension:

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

Edit: the attribute error you were getting is because the append() method of a list returns None. Since you assign the output of the method to the list1 variable, you overwrite the list with None on the first time around the loop. Since None does not have a append method, on the next time around the loop you get the error. Removing this assignment makes your code work:

>>> 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']]
Blair
  • 15,356
  • 7
  • 46
  • 56
  • 1
    It's an `AttributeError`, not a `SyntaxError`. (Still +1 for being not only the first recommendation for a list comprehension, but the only one that explained why to use one and gave a link.) – abarnert Nov 02 '12 at 23:33
  • Thank you for explaining what my error was. Thank you everyone for all your help. – Israel CA Nov 02 '12 at 23:57
3
>>> 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']]

The list constructor is applied to each element of the original list. And the elements of the original list are strings, which are iterables. So list just consumes the string treating it as iterator, so eventually it contains the letters (as strings yields letters as elements if it's being iterated over).

ovgolovin
  • 13,063
  • 6
  • 47
  • 78
1

You can simply coerce a string into a list to get a list of the string's characters.

words = ['BLUE', 'ORANGE', 'YELLOW', 'GREEN', 'BLACK', 'PURPLE', 'BROWN']
split_words = [list(word) for word in li]
Acorn
  • 49,061
  • 27
  • 133
  • 172
  • Judging by what he tried, he wasn't having any problem with the `list(word)` part, but with putting all the results together (the trivial list comprehension). – abarnert Nov 02 '12 at 23:27
1

The only reason your existing code doesn't work is that list.append modifies a list in place, and returns None. So:

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

The first time through, you're adding the first word onto list_1, and then setting list_1 to None. So the next time through, you get an AttributeError.

Just do this:

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

Or use a function that doesn't modify the list in-place, but instead returns a new one:

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

It's a bit silly to loop over range(len(first_list)) if all you want with the index i is first_list[i]; you can just loop over first_list directly. (And even if you do need i for other purposes, you can loop over enumerate(first_list).)

However, as many people have pointed out, it's almost always better to use a list comprehension than to try to build the list with an explicit loop.

In fact, one of the many reasons for that is that you don't have to remember append vs. extend, which functions mutate and which return new values, and so on.

abarnert
  • 354,177
  • 51
  • 601
  • 671
0

This will do:

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']]
Netwave
  • 40,134
  • 6
  • 50
  • 93
0

You can apply list() to each item using 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']]

Although I'm not sure why you'd need to do this. Strings and lists behave almost identically.

Blender
  • 289,723
  • 53
  • 439
  • 496
0

Your current solution doesn't work because list.append() returns None, and you are assigning the result of list_1.append() back to list_1, so on the second iteration you get the attribute error.

Here is how you could fix your current code:

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

A better solution would be to loop over the items in the list directly:

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

But the best way to do this is to use a list comprehension or map, as in the other answers.

Andrew Clark
  • 202,379
  • 35
  • 273
  • 306