nesting python list comprehensions to construct a

2019-04-30 10:53发布

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)

7条回答
够拽才男人
2楼-- · 2019-04-30 11:27
>>> f = file('teste.txt')
>>> print map(lambda x: [c for c in x][:-1], f)
[['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']]
查看更多
女痞
3楼-- · 2019-04-30 11:34

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

f = open(r"temp.txt")
[[c for c in line] for line in f]
查看更多
劳资没心,怎么记你
4楼-- · 2019-04-30 11:35

Here is one level of list comprehension.

data = []
f = open(file,'r')

for line in f:
    data.append([ch for ch in line.strip().upper()])

But we can do the whole thing on one go:

f = open(file, 'rt')
data = [list(line.strip().upper()) for line in f]

This is using list() to convert a string to a list of single-character strings. We could also use nested list comprehensions, and put the open() inline:

data = [[ch for ch in line.strip().upper()] for line in open(file, 'rt')]

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

查看更多
Luminary・发光体
5楼-- · 2019-04-30 11:37
data = [list(line.strip().upper()) for line in open(file,'r')]
查看更多
爱情/是我丢掉的垃圾
6楼-- · 2019-04-30 11:41

In your case, you can use the list constructor to handle the inner loop and use list comprehension for the outer loop. Something like:

f = open(file)
data = [list(line.strip().upper()) for line in f]

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:

data = []
for line in f:
    data.append(list(line.strip().upper()))
查看更多
\"骚年 ilove
7楼-- · 2019-04-30 11:44

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:

data = [line.strip() for line in open(filename, 'r')]

When I needed to manipulate strings in data as mutable lists, I'd use list to convert them, and join to put them back, e.g.:

data[2] = ''.join(sorted(list(data[2])))

Of course, if all you're going to do with these strings is modify them, then go ahead, store them as lists.

查看更多
登录 后发表回答