use*_*974 30 python performance list-comprehension list
假设我有一个列表:
l=['a','b','c']
Run Code Online (Sandbox Code Playgroud)
及其后缀列表:
l2 = ['a_1', 'b_1', 'c_1']
Run Code Online (Sandbox Code Playgroud)
我希望所需的输出为:
out_l = ['a','a_1','b','b_2','c','c_3']
Run Code Online (Sandbox Code Playgroud)
结果是上面两个列表的交错版本.
我可以编写常规for循环来完成这项工作,但我想知道是否有更多Pythonic方式(例如,使用list comprehension或lambda)来完成它.
我尝试过这样的事情:
list(map(lambda x: x[1]+'_'+str(x[0]+1), enumerate(a)))
# this only returns ['a_1', 'b_2', 'c_3']
Run Code Online (Sandbox Code Playgroud)
此外,对于一般情况需要做出哪些改变,即对于2个或更多列表,其中l2不一定是衍生物l?
cs9*_*s95 67
yield您可以使用生成器来获得优雅的解决方案.在每次迭代时,对原始元素产生两次 -once,对具有添加后缀的元素产生一次.
发电机需要耗尽; 这可以通过list最后加入电话来完成.
def transform(l):
for i, x in enumerate(l, 1):
yield x
yield f'{x}_{i}' # {}_{}'.format(x, i)
Run Code Online (Sandbox Code Playgroud)
您也可以使用yield from生成器委派的语法重写它:
def transform(l):
for i, x in enumerate(l, 1):
yield from (x, f'{x}_{i}') # (x, {}_{}'.format(x, i))
Run Code Online (Sandbox Code Playgroud)
out_l = list(transform(l))
print(out_l)
['a', 'a_1', 'b', 'b_2', 'c', 'c_3']
Run Code Online (Sandbox Code Playgroud)
如果您使用的是早于python-3.6的版本,请替换f'{x}_{i}'为'{}_{}'.format(x, i).
概括
考虑一般情况,您有N个表格列表:
l1 = [v11, v12, ...]
l2 = [v21, v22, ...]
l3 = [v31, v32, ...]
...
Run Code Online (Sandbox Code Playgroud)
你想要交错.这些列表不一定是相互派生的.
要使用这N个列表处理交叉操作,您需要迭代对:
def transformN(*args):
for vals in zip(*args):
yield from vals
out_l = transformN(l1, l2, l3, ...)
Run Code Online (Sandbox Code Playgroud)
list.__setitem__我从性能的角度推荐这个.首先为空列表分配空间,然后使用切片列表分配将列表项分配到其适当的位置.l进入偶数索引,l'(l修改)进入奇数索引.
out_l = [None] * (len(l) * 2)
out_l[::2] = l
out_l[1::2] = [f'{x}_{i}' for i, x in enumerate(l, 1)] # [{}_{}'.format(x, i) ...]
Run Code Online (Sandbox Code Playgroud)
print(out_l)
['a', 'a_1', 'b', 'b_2', 'c', 'c_3']
Run Code Online (Sandbox Code Playgroud)
从我的时间(下图)开始,这一直是最快的.
概括
为了处理N个列表,迭代地分配给切片.
list_of_lists = [l1, l2, ...]
out_l = [None] * len(list_of_lists[0]) * len(list_of_lists)
for i, l in enumerate(list_of_lists):
out_l[i::2] = l
Run Code Online (Sandbox Code Playgroud)
zip + chain.from_iterable一种功能性方法,类似于@chrisz的解决方案.使用构建对zip,然后使用它来展平它itertools.chain.
from itertools import chain
# [{}_{}'.format(x, i) ...]
out_l = list(chain.from_iterable(zip(l, [f'{x}_{i}' for i, x in enumerate(l, 1)])))
Run Code Online (Sandbox Code Playgroud)
print(out_l)
['a', 'a_1', 'b', 'b_2', 'c', 'c_3']
Run Code Online (Sandbox Code Playgroud)
iterools.chain 被广泛认为是pythonic列表展平方法.
推广
这是最简单的推广解决方案,我怀疑当N很大时,多个列表的效率最高.
list_of_lists = [l1, l2, ...]
out_l = list(chain.from_iterable(zip(*list_of_lists)))
Run Code Online (Sandbox Code Playgroud)
让我们看看两个列表的简单情况(一个带有后缀的列表)的一些性能测试.一般情况不会被测试,因为结果因数据而异.
def cs1(l):
def _cs1(l):
for i, x in enumerate(l, 1):
yield x
yield f'{x}_{i}'
return list(_cs1(l))
def cs2(l):
out_l = [None] * (len(l) * 2)
out_l[::2] = l
out_l[1::2] = [f'{x}_{i}' for i, x in enumerate(l, 1)]
return out_l
def cs3(l):
return list(chain.from_iterable(
zip(l, [f'{x}_{i}' for i, x in enumerate(l, 1)])))
def ajax(l):
return [
i for b in [[a, '{}_{}'.format(a, i)]
for i, a in enumerate(l, start=1)]
for i in b
]
def ajax_cs0(l):
# suggested improvement to ajax solution
return [j for i, a in enumerate(l, 1) for j in [a, '{}_{}'.format(a, i)]]
def chrisz(l):
return [
val
for pair in zip(l, [f'{k}_{j+1}' for j, k in enumerate(l)])
for val in pair
]
Run Code Online (Sandbox Code Playgroud)
def transform(l):
for i, x in enumerate(l, 1):
yield x
yield f'{x}_{i}' # {}_{}'.format(x, i)
Run Code Online (Sandbox Code Playgroud)
System-Mac OS X High Sierra-2.4 GHz Intel Core i7
Python-3.6.0
IPython-6.2.1
你可以像这样使用列表理解:
l=['a','b','c']
new_l = [i for b in [[a, '{}_{}'.format(a, i)] for i, a in enumerate(l, start=1)] for i in b]
Run Code Online (Sandbox Code Playgroud)
输出:
['a', 'a_1', 'b', 'b_2', 'c', 'c_3']
Run Code Online (Sandbox Code Playgroud)
可选,更短的方法:
[j for i, a in enumerate(l, 1) for j in [a, '{}_{}'.format(a, i)]]
Run Code Online (Sandbox Code Playgroud)
你可以使用zip:
[val for pair in zip(l, [f'{k}_{j+1}' for j, k in enumerate(l)]) for val in pair]
Run Code Online (Sandbox Code Playgroud)
输出:
['a', 'a_1', 'b', 'b_2', 'c', 'c_3']
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3256 次 |
| 最近记录: |