Reputation: 55
Long story short, I am trying to work with some crazy data I collected yesterday. A quick nested for loop would do this real easy but right now, I just want to get my nested list comprehension to work. There are a bunch of post on this subject and I am not sure whether it is just me or the because of Friday evening, I can't get it to work. My list comphrension is in format:
[ [str(j[0], sanitize(j[1]) for j in i.split(',')] for i in b]
where b is ['string, float\t\n', 'string, float\t\n']
or b might be a file object or whatever, doesn't matter a heck lot.
I could simply do something like
for i in b:
out.append(str(j[0]), sanitize(j[1])
But, it should be possible by list comprehension. IT SHOULD!!! And, somehow, I am not getting it right.
Now, on to what I have done so far...
>>> b
['08:54:55, 0.031250\n', '08:55:57, 0.031250\n']
>>> [i.split(',') for i in b]
[['08:54:55', ' 0.031250\n'], ['08:55:57', ' 0.031250\n']]
What I want:
[['08:54:55', 0.031250], ['08:55:57', 0.031250]]
A multiple list comprehension should do the trick:
Something like:
[ [j[0], j[1]] for j in i.split(',') for i in b] # the cleaning/str/float would be something like: str(j[0]), float(j[1])
BUT, this is what I get.
>>> [ [j[0], j[1]] for j in i.split(',') for i in b]
[['0', '8'], ['0', '8'], [' ', '0'], [' ', '0']]
>>>
>>> [ [j[1]] for j in i.split(',') for i in b]
[['8'], ['8'], ['0'], ['0']]
Any attempt to work on j[0] or j[1] does not pan out.
To figure out what was going on, I did this:
>>> [ [ pprint(type(j)) for j in i.split(',')] for i in b]
<type 'str'>
<type 'str'>
<type 'str'>
<type 'str'>
[[None, None], [None, None]]
If I don't mess with j[0]
or j[1]
,
>>> [ [ j for j in i.split(',')] for i in b]
[['08:54:55', ' 0.031250\n'], ['08:55:57', ' 0.031250\n']]
The example with pprint(type(j))
means even if I were to write an external function, it would not do the trick. I would simply be getting an empty list back from the list comprehension.
What am I doing wrong? A lambda might do the trick?
Upvotes: 0
Views: 4393
Reputation: 30288
You can create a second for
comprehension to extra the split()
:
>>> [[t, sanitize(v)] for i in b for t, v in [i.split(',')]]
[['08:54:55', 0.031250], ['08:55:57', 0.031250]]
Upvotes: 4
Reputation: 225273
If you write out a proper, working loop:
out = []
for i in b:
j = i.split(',')
out.append((j[0], sanitize(j[1])))
you’ll notice that you need somewhere to store the result of i.split(',')
to avoid repeating it. This isn’t possible inline in one list comprehension. You can write a function:
def convert_thing(thing):
time, value = thing.split(',')
return time, sanitize(value)
out = [convert_thing(x) for x in b]
or generate intermediate values (don’t do this):
out = [(time, sanitize(value)) for time, value in (x.split(',') for x in b)]
# this bit is a generator expression ^^^^^^^^^^^^^^^^^^^^^^^^^
Upvotes: 1