I'm a python newb and am having trouble groking nested list comprehensions. I'm trying to write some code to read in a file and construct a list for each character for each line.
so if the file contains
xxxcd
cdcdjkhjasld
asdasdxasda
The resulting list would be:
[
['x','x','x','c','d']
['c','d','c','d','j','k','h','j','a','s','l','d']
['a','s','d','a','s','d','x','a','s','d','a']
]
I have written the following code, and it works, but I have a nagging feeling that I should be able to write a nested list comprehension to do this in fewer lines of code. any suggestions would be appreciated.
data = []
f = open(file,'r')
for line in f:
line = line.strip().upper()
list = []
for c in line:
list.append(c)
data.append(list)
This should help (you'll probably have to play around with it to strip the newlines or format it however you want, but the basic idea should work):
Here is one level of list comprehension.
But we can do the whole thing on one go:
This is using
list()
to convert a string to a list of single-character strings. We could also use nested list comprehensions, and put theopen()
inline:At this point, though, I think the list comprehensions are detracting from easy readability of what is going on.
For complicated processing, such as lists inside lists, you might want to use a
for
loop for the outer layer and a list comprehension for the inner loop.Also, as Chris Lutz said in a comment, in this case there really isn't a reason to explicitly split each line into character lists; you can always treat a string as a list, and you can use string methods with a string, but you can't use string methods with a list. (Well, you could use
''.join()
to rejoin the list back to a string, but why not just leave it as a string?)In your case, you can use the
list
constructor to handle the inner loop and use list comprehension for the outer loop. Something like:Given a string as input, the list constructor will create a list where each character of the string is a single element in the list.
The list comprehension is functionally equivalent to:
The only really significant difference between strings and lists of characters is that strings are immutable. You can iterate over and slice strings just as you would lists. And it's much more convenient to handle strings as strings, since they support string methods and lists don't.
So for most applications, I wouldn't bother converting the items in
data
to a list; I'd just do:When I needed to manipulate strings in
data
as mutable lists, I'd uselist
to convert them, andjoin
to put them back, e.g.:Of course, if all you're going to do with these strings is modify them, then go ahead, store them as lists.