2017-08-05 4 views
1

Wenn ich eine Liste z.Hinzufügen von Elementen zwischen Elementen in der Liste

[1,2,3] 

und eine Funktion f(), wie füge ich, so dass die neue Liste ist wie:

[1, f(1), 2, f(2), 3, f(3)]? 
+0

Haben Sie versucht, hier etwas zu Ihrer Lösung zu bekommen? Es wäre schön, wenn Sie versuchen würden, Ihre Probleme zu beheben. – idjaw

+0

[https://docs.python.org/2/tutorial/datastructures.html](https://docs.python.org/2/tutorial/datastructures.html) – clabe45

Antwort

4

Sie verwenden können:

[y for x in data for y in (x,f(x))] 

mit data die erste Liste, und f natürlich die Funktion, die Sie anwenden möchten.

Zum Beispiel, wenn f das ist str Funktion (konvertiert eine Zahl in ihrem textlichen äquivalent), wird es generieren:

>>> data = [1,2,3] 
>>> f = str 
>>> [y for x in data for y in (x,f(x))] 
[1, '1', 2, '2', 3, '3'] 

So, hier bekommen wir [1, '1', 2, '2', 3, '3'] wo 1 ist die anfängliche 1 und '1' ist f(1).

Benchmarks: Ich änderte die following test setup zu:

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

Dies bedeutet, dass wir die verschiedenen Antworten für verschiedene Dateigrößen mit Pandas testen. Für jede Konfiguration führen wir 10 Tests mit timeit durch.

Dies erzeugt die folgenden Zeitpunkten (in Sekunden):

   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 

oder in relativ (am besten ist 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 
1
>>> 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] 
2

Ein etwas anderer Ansatz von Willem Antwort, dass vermeidet zwei Schleifen:

sum([[x,f(x)] for x in my_list], []) 
  • [x, f(x)] erstellt eine Liste von zwei Elementen mit dem aktuellen Element und der angewendeten Funktion.

  • sum(..., []) flacht die Liste ab.

+2

Richtig, weil 'sum' ohne Schleife funktioniert, und wiederholte Listenverkettungen sind effizienter ... Das ist viel schlimmer; eine Schleife zu haben ist keine schlechte Sache. – poke

+2

Hat nicht dv (did +1), aber es ist nicht, weil Sie keine Schleife sehen, dass es keine Schleife gibt. Slicing oder extending arbeitet intern mit Loops ... Die einzige Frage, die ich habe, ist, ob Python '__add__' oder' __iadd__' verwendet, weil dies im ersten Fall zu einem * O (n^2) * -Algorithmus führt. –

+1

Basiert auf einem schnellen Experiment, der Anfangswert '[]' wird nicht aktualisiert. Das heißt wahrscheinlich, dass es '__add__' verwendet. Diese [Frage] (https://stackoverflow.com/questions/31054393/why-doesnt-python-take-advantage-of-iadd-for-sum-and-chained-operators) bestätigt es. –

4
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] 
1

können Sie verwenden map und 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) 

Ausgang:

[1, 1, 2, 8, 3, 27] 
Verwandte Themen