Skip to main content
 首页 » 编程设计

python之在没有嵌套 for 循环的情况下在 Python 中明智地连接两个字符串列表

2025年05月04日23qlqwjy

我有两个字符串列表: ls1 = ['a','b','c','d'] 和 ls2 = ['k','j','l','m']

我想创建第三个列表:ls3 = ['a-k','a-j','a-l','a-m','b-k','b- j','b-l','b-m'...'d-m'] 有 16 个元素。

我可以使用下面的嵌套 for 循环很容易地实现这一点

ls3 = []  
for elem in ls1: 
    for item in ls2: 
        ls3.append(elem+'-'+item) 

但是,这不是很 Pythonic 并且揭示了我的 C 代码背景。

我尝试使用 map 和 lambda 进行更 Pythonic 的解决方案:

[ map(lambda x,y: x+'-'+y, a,b) for a,b in zip(ls1,ls2) ] 

但我还不知道我在做什么。

什么是 Pythonic 方法来实现我用嵌套的 for 循环所做的事情?

请您参考如下方法:

您可以将 itertools.product 与 map 一起使用:

list(map('-'.join, itertools.product('abcd', 'kjlm'))) 
# ['a-k', 'a-j', 'a-l', 'a-m', 'b-k', 'b-j', 'b-l', 'b-m', 'c-k', 'c-j', 'c-l', 'c-m', 'd-k', 'd-j', 'd-l', 'd-m'] 

测试正确性和时间:

通常的基准免责声明适用。

在测试条件下,上述 ("product map") 解决方案比 "naive"列表理解 ("naive") 更快,尽管差距很小对于小问题。

大部分加速似乎是由于避免了列表理解。事实上,如果 map 被列表理解(“product compr”)替换,那么 product 仍然比原始方法更好地扩展,但在小问题上尺寸落后:

small (4x4) 
results equal: True True 
naive             0.002420 ms 
product compr     0.003211 ms 
product map       0.002146 ms 
large (4x4x4x4x4x4) 
results equal: True True 
naive             0.836124 ms 
product compr     0.681193 ms 
product map       0.385240 ms 

引用基准脚本

import itertools 
import timeit 
 
lists = [[chr(97 + 4*i + j) for j in range(4)] for i in range(6)] 
 
print('small (4x4)') 
print('results equal:', [x+'-'+y for x in lists[0] for y in lists[1]] 
      == 
      list(map('-'.join, itertools.product(lists[0], lists[1]))), end=' ') 
print(['-'.join(t) for t in  itertools.product(lists[0], lists[1])] 
      == 
      list(map('-'.join, itertools.product(lists[0], lists[1])))) 
 
print('{:16s} {:9.6f} ms'.format('naive', timeit.timeit(lambda: [x+'-'+y for x in lists[0] for y in lists[1]], number=1000))) 
print('{:16s} {:9.6f} ms'.format('product compr', timeit.timeit(lambda: ['-'.join(t) for t in itertools.product(lists[0], lists[1])], number=1000))) 
print('{:16s} {:9.6f} ms'.format('product map', timeit.timeit(lambda: list(map('-'.join, itertools.product(lists[0], lists[1]))), number=1000))) 
 
print('large (4x4x4x4x4x4)') 
print('results equal:', ['-'.join((u, v, w, x, y, z)) for u in lists[0] for v in lists[1] for w in lists[2] for x in lists[3] for y in lists[4] for z in lists[5]] 
      == 
      list(map('-'.join, itertools.product(*lists))), end=' ') 
print(['-'.join(t) for t in  itertools.product(*lists)] 
      == 
      list(map('-'.join, itertools.product(*lists)))) 
 
print('{:16s} {:9.6f} ms'.format('naive', timeit.timeit(lambda: ['-'.join((u, v, w, x, y, z)) for u in lists[0] for v in lists[1] for w in lists[2] for x in lists[3] for y in lists[4] for z in lists[5]], number=1000))) 
print('{:16s} {:9.6f} ms'.format('product compr', timeit.timeit(lambda: ['-'.join(t) for t in  itertools.product(*lists)], number=1000))) 
print('{:16s} {:9.6f} ms'.format('product map', timeit.timeit(lambda: list(map('-'.join, itertools.product(*lists))), number=1000)))