Reputation: 1854
If I have a list eg.
[1,2,3]
and a function f(), how do I insert such that the new list is like:
[1, f(1), 2, f(2), 3, f(3)]?
Upvotes: 1
Views: 115
Reputation: 476659
You can use:
[y for x in data for y in (x,f(x))]
with data
the initial list, and f
of course the function you want to apply.
For example if f
is the str
function (converts a number to its textual equivalent), it will generate:
>>> data = [1,2,3]
>>> f = str
>>> [y for x in data for y in (x,f(x))]
[1, '1', 2, '2', 3, '3']
So here we obtain [1, '1', 2, '2', 3, '3']
where 1
is the initial 1
, and '1'
is f(1)
.
Benchmarks: I altered the following test setup to:
import pandas as pd
from timeit import timeit
from itertools import chain
wvo = lambda d, f: [y for x in d for y in (x,f(x))]
max = lambda d, f: list(chain.from_iterable(zip(d, map(f, d))))
mrc = lambda d, f: sum([[x,f(x)] for x in d], [])
chi = lambda d,f: [j for k in map(lambda x: (x, f(x)), d) for j in k]
mar = lambda d,f: [ee for e in zip (d, map (f, d)) for ee in e]
results = pd.DataFrame(
index=pd.Index([1, 3, 10, 30, 100, 300,
1000, 3000, 10000, 30000, 100000], name='N'),
columns='wvo max mrc chi mar'.split(),
dtype=float
)
for i in results.index:
pd.concat([df] * i, ignore_index=True)
d = list(range(i))
f = str
for j in results.columns:
stmt = '{}(d,f)'.format(j)
setp = 'from __main__ import d, f, {}'.format(j)
results.set_value(i, j, timeit(stmt, setp, number=10))
This means we can test the different answers for different file sizes using pandas. For every configuration, we perform 10 tests with timeit.
This generates the following timings (in seconds):
wvo max mrc chi mar
N
1 0.000016 0.000029 0.000018 0.000022 0.000020
3 0.000026 0.000029 0.000031 0.000034 0.000026
10 0.000057 0.000053 0.000061 0.000076 0.000062
30 0.000145 0.000122 0.000210 0.000200 0.000145
100 0.000440 0.000347 0.000899 0.000588 0.000407
300 0.001263 0.000637 0.004416 0.001721 0.000680
1000 0.002425 0.001897 0.040877 0.003796 0.002325
3000 0.009269 0.009798 0.289162 0.015486 0.008430
10000 0.037131 0.032563 3.823171 0.044008 0.030609
30000 0.078577 0.060828 53.803486 0.096703 0.066899
100000 0.255477 0.195669 1094.482380 0.289030 0.191143
Or in relative terms (best is 1.00
):
wvo max mrc chi mar Best
N
1 1.00 1.78 1.11 1.36 1.19 wvo
3 1.03 1.15 1.23 1.32 1.00 mar
10 1.08 1.00 1.17 1.45 1.18 max
30 1.19 1.00 1.73 1.65 1.20 max
100 1.27 1.00 2.59 1.69 1.17 max
300 1.98 1.00 6.93 2.70 1.07 max
1000 1.28 1.00 21.55 2.00 1.23 max
3000 1.10 1.16 34.30 1.84 1.00 mar
10000 1.21 1.06 124.90 1.44 1.00 mar
30000 1.29 1.00 884.52 1.59 1.10 max
100000 1.34 1.02 5725.98 1.51 1.00 mar
Upvotes: 4
Reputation: 9257
You can use map
and list comprehension
:
f = lambda x: x**3
a = [1, 2, 3]
output = [j for k in map(lambda x: (x, f(x)), a) for j in k]
print(output)
Output:
[1, 1, 2, 8, 3, 27]
Upvotes: 1
Reputation: 210842
In [18]: lst = [1,2,3]
In [19]: def f(x):
...: return x**2
...:
In [20]: from itertools import chain
In [21]: list(chain.from_iterable(zip(lst, map(f, lst))))
Out[21]: [1, 1, 2, 4, 3, 9]
Upvotes: 4
Reputation: 4795
A slightly different approach from Willem's answer, that avoids two loops:
sum([[x,f(x)] for x in my_list], [])
[x, f(x)]
creates a list of two elements with the current element and the function applied to it.
sum(..., [])
flattens the list.
Upvotes: 2
Reputation: 1147
>>> data = [1, 2, 3]
>>> f = lambda x : x + 1
>>> [ee for e in zip (data, map (f, data)) for ee in e]
[1, 2, 2, 3, 3, 4]
Upvotes: 1