drevicko
drevicko

Reputation: 15180

creating a list with 2 entries for each element of an iterator

I'm looking for a more elegant way to do something like this:

[data[i/2] if i%2==0 else log10(data[i/2]) for i in xrange(len(data)*2)]

So if data was [1,10,100], I want to make a list:

[1,0,10,1,100,2]

fyi: this is for output to a csv file

Upvotes: 1

Views: 108

Answers (4)

drevicko
drevicko

Reputation: 15180

Excuse me for answering my own question, but the answers here inspired me to play around a bit, and I came to something that is significantly faster than the above:

import itertools
import numpy
data = range(1,10000)
[x for y,z in itertools.izip(data,numpy.log10(data)) for x in (y, z)]

The point is that numpy.log10() is more efficient than calling math.log10() many times. With 10000 integers, I got 4.59 msec vs 32.8 msec for Ignacio's list comprehension, 32.9 msec for JBernaro's chain() and 482 msec for Karl's sum(). I guess the sum() version loses out when it allocates a length 2 list for every x-value.

Upvotes: 0

Karl Knechtel
Karl Knechtel

Reputation: 61557

sum(([x, math.log10(x)] for x in data), [])

Upvotes: 1

JBernardo
JBernardo

Reputation: 33407

data = [1,10,100]
itertools.chain(*((x,log10(x)) for x in data))

then make a list

Upvotes: 1

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 798814

>>> data = [1, 10, 100]
>>> [x for y in data for x in (y, math.log10(y))]
[1, 0.0, 10, 1.0, 100, 2.0]

Upvotes: 1

Related Questions