2017-08-05 138 views
1

如果我有一个列表,例如。在列表中的元素之间添加元素

[1,2,3] 

和函数f(),我怎么插入这样,新的名单是这样的:

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

你尝试过什么这里去您的解决方案?很高兴看到您尝试帮助您解决问题。 – idjaw

+0

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

回答

4

您可以使用:

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

data的初步名单,和f当然是你想要应用的功能。

例如,如果fstr功能(可将数字转换为其文本等值),它会产生:

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

所以在这里我们得到[1, '1', 2, '2', 3, '3']其中1是初始1,并且'1'f(1)

基准:我改变了following test setup到:

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

这意味着我们可以测试使用大熊猫不同的文件大小不同的答案。对于每一个配置,我们用timeit执行10次测试。

这将生成以下计时(秒):

   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 

或者相对而言(最好是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

稍微不同的方法,即避免了两个循环:

sum([[x,f(x)] for x in my_list], []) 
  • [x, f(x)]创建与当前元素两个元件和适用于它的功能的列表。

  • sum(..., [])平展列表。

+2

对,因为'sum'没有循环,而重复的列表连接更有效率......这更糟糕;有一个循环不是一件坏事。 – poke

+2

没有dv(做+1),但它不是因为你没有看到一个循环,没有循环。切片或扩展内部循环的作品... 我唯一的问题是Python是否使用'__add__'或'__iadd__',因为在前一种情况下,这将导致* O(n^2)*算法。 –

+1

根据快速实验,初始值'[]'不会更新。所以这可能意味着它使用'__add__'。这[问题](https://stackoverflow.com/questions/31054393/why-doesnt-python-take-advantage-of-iadd-for-sum-and-chained-operators)证实了它。 –

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

您可以使用maplist 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) 

输出:

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