2009-12-10 9 views
5

J'ai une liste de listes (générée par une simple compréhension de la liste):Conversion d'une liste de listes à un tuple en Python

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

Je veux tourner cette liste entière en un tuple contenant toutes les valeurs dans les listes, à savoir:

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

Quelle serait la manière la plus efficace de le faire? (Une façon de générer ce même tuple avec la compréhension de la liste serait aussi une réponse acceptable.) J'ai regardé les réponses ici et dans la documentation de Python, mais je n'ai pas réussi à en trouver une qui convienne.

EDIT:

Un grand merci à tous ceux qui ont répondu!

Répondre

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

Modifier: Notez que, avec base_lists si courte, la Genexp (avec mémoire illimitée disponible) est lente. Considérez le fichier suivant 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)) 

maintenant:

$ 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 

Lorsque les listes sont plus longs (à savoir, lorsque la performance est vraiment) les choses sont un peu différentes. Par exemple, mettre un 100 * sur l'ERS définit 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 

donc pour les longues que withsum est une catastrophe de performance - les autres sont dans le même ordre de grandeur, bien qu'il soit clair itertools a bord, et compréhensions de liste (lorsque mémoire abondante est disponible, comme il sera toujours dans microbenchmarks ;-) sont plus rapides que genexps.

En utilisant 1000 *, Genexp ralentit d'environ 10 fois (wrt le 100 *), withit et listcomp d'environ 12 fois, et withsum d'environ 180 fois (withsum est O(N squared), plus il commence à souffrir de la fragmentation grave du tas à ce Taille).

+0

Est-ce que précisément ce que je dois. Merci Alex! –

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

Utiliser sum pour n'importe quoi sauf les nombres est une mauvaise idée (comme j'ai souvent essayé d'expliquer dans SO - j'étais l'auteur de la somme de Python donc je ressens un sentiment de culpabilité chaque fois que je le vois mal utilisé ;-) . Indice: O (N au carré). –

+0

Ouch, bon à savoir merci Alex. Je suppose qu'il y aura une bonne raison pour laquelle il ne peut pas être O (N):/ –

2

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

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

A voté pour l'utilisation de itertools, qui est un module sous-estimé –

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