5

我有一个列表列表(使用简单的列表理解生成):

>>> base_lists = [[a, b] for a in range(1, 3) for b in range(1, 6)]
>>> base_lists

[[1,1],[1,2],[1,3],[1,4],[1,5],[2,1],[2,2],[2,3],[2,4],[2,5]]

我想把整个列表变成一个包含列表中所有值的元组,即:

resulting_tuple = (1,1,1,2,1,3,1,4,1,5,2,1,2,2,2,3,2,4,2,5)

最有效的方法是什么?(使用列表理解生成相同元组的方法也是可接受的答案。)我已经查看了此处和 Python 文档中的答案,但是我一直无法找到合适的答案。

编辑:

非常感谢所有回答的人!

4

5 回答 5

11
tuple(x for sublist in base_lists for x in sublist)

编辑:请注意,base_lists如此短,genexp(可用无限内存)很慢。考虑以下文件tu.py

base_lists = [[a, b] for a in range(1, 3) for b in range(1, 6)]

def genexp():
  return tuple(x for sublist in base_lists for x in sublist)

def listcomp():
  return tuple([x for sublist in base_lists for x in sublist])

def withsum():
  return tuple(sum(base_lists,[]))

import itertools as it

def withit():
  return tuple(it.chain(*base_lists))

现在:

$ python -mtimeit -s'import tu' 'tu.genexp()'
100000 loops, best of 3: 7.86 usec per loop
$ python -mtimeit -s'import tu' 'tu.withsum()'
100000 loops, best of 3: 5.79 usec per loop
$ python -mtimeit -s'import tu' 'tu.withit()'
100000 loops, best of 3: 5.17 usec per loop
$ python -mtimeit -s'import tu' 'tu.listcomp()'
100000 loops, best of 3: 5.33 usec per loop

当列表更长时(即,当性能真的很重要时)情况会有所不同。例如,100 *在 RHS 上定义base_lists

$ python -mtimeit -s'import tu' 'tu.genexp()'
1000 loops, best of 3: 408 usec per loop
$ python -mtimeit -s'import tu' 'tu.withsum()'
100 loops, best of 3: 5.07 msec per loop
$ python -mtimeit -s'import tu' 'tu.withit()'
10000 loops, best of 3: 148 usec per loop
$ python -mtimeit -s'import tu' 'tu.listcomp()'
1000 loops, best of 3: 278 usec per loop

因此,只有长列表withsum才是性能灾难——其他人在同一个球场上,尽管显然itertools有优势,并且列表理解(当有足够的内存可用时,因为它总是在微基准中;-)比 genexps 更快。

使用1000 *, genexp 减慢了大约 10 倍(wrt the 100 *), withit 和 listcomp 减慢了约 12 倍, withsum 减慢了约 180 倍(withsum 是O(N squared),而且它开始遭受该大小的严重堆碎片)。

于 2009-12-10T22:00:10.750 回答
5
from itertools import chain
base_lists = [[a, b] for a in range(1, 3) for b in range(1, 6)]

print tuple(chain(*base_lists))
于 2009-12-10T22:07:38.837 回答
3
>>> sum(base_lists,[])
[1, 1, 1, 2, 1, 3, 1, 4, 1, 5, 2, 1, 2, 2, 2, 3, 2, 4, 2, 5]
>>> tuple(sum(base_lists,[]))
(1, 1, 1, 2, 1, 3, 1, 4, 1, 5, 2, 1, 2, 2, 2, 3, 2, 4, 2, 5)
于 2009-12-10T22:02:08.890 回答
2

resulting_tuple = tuple(item for l in base_lists for item in l)

于 2009-12-10T22:05:18.120 回答
0
>>> arr=[]
>>> base_lists = [[a, b] for a in range(1, 3) for b in range(1, 6)]
>>> [ arr.extend(i) for i in base_lists ]
[None, None, None, None, None, None, None, None, None, None]
>>> arr
[1, 1, 1, 2, 1, 3, 1, 4, 1, 5, 2, 1, 2, 2, 2, 3, 2, 4, 2, 5]
>>> tuple(arr)
(1, 1, 1, 2, 1, 3, 1, 4, 1, 5, 2, 1, 2, 2, 2, 3, 2, 4, 2, 5)
于 2009-12-11T07:16:20.553 回答