Mat.S
Mat.S

Reputation: 1854

Adding elements between elements in list

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

Answers (5)

willeM_ Van Onsem
willeM_ Van Onsem

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

Chiheb Nexus
Chiheb Nexus

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

MaxU - stand with Ukraine
MaxU - stand with Ukraine

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

Mr. Xcoder
Mr. Xcoder

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

marsouf
marsouf

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

Related Questions