web-dev-qa-db-fra.com

Transformez la "liste de tuples" en une liste plate ou une matrice

Avec Sqlite, une commande "select..from" renvoie les résultats "output", qui s'affichent (en python):

>>print output
[(12.2817, 12.2817), (0, 0), (8.52, 8.52)]

Il semble que ce soit une liste de tuples. Je voudrais convertir la "sortie" dans un simple tableau 1D (= liste dans Python je suppose):

[12.2817, 12.2817, 0, 0, 8.52, 8.52]

ou une matrice 2x3:

12.2817 12.2817
0          0 
8.52     8.52

à lire via "sortie [i] [j]"

La commande aplatir ne fait pas le travail pour la 1ère option, et je n'ai aucune idée pour la seconde ... :)

Pourriez-vous s'il vous plaît me donner un indice? Quelque chose de rapide serait génial car les données réelles sont beaucoup plus grandes (voici juste un exemple simple).

56
garth

La solution de loin la plus rapide (et la plus courte) publiée:

list(sum(output, ()))

Environ 50% plus rapide que la solution itertools et environ 70% plus rapide que la solution map.

99
Joel Cornett

Lister l'approche de compréhension qui fonctionne avec les types Iterables et qui est plus rapide que les autres méthodes présentées ici.

flattened = [item for sublist in l for item in sublist]

l est la liste à aplatir (appelée output dans le cas de l'OP)


tests timeit:

l = list(Zip(range(99), range(99)))  # list of tuples to flatten

Compréhension des listes

[item for sublist in l for item in sublist]

résultat timeit = 7,67 µs ± 129 ns par boucle

Liste méthode extend ()

flattened = []
list(flattened.extend(item) for item in l)

résultat timeit = 11 µs ± 433 ns par boucle

somme()

list(sum(l, ()))

résultat timeit = 24,2 µs ± 269 ns par boucle

20
Gman

Dans Python 3, vous pouvez utiliser le * syntaxe pour aplatir une liste d'itérables:

>>> t = [ (1,2), (3,4), (5,6) ]
>>> t
[(1, 2), (3, 4), (5, 6)]
>>> import itertools
>>> list(itertools.chain(*t))
[1, 2, 3, 4, 5, 6]
>>> 
14
Thruston

Ou vous pouvez aplatir la liste comme ceci:

reduce(lambda x,y:x+y, map(list, output))
7
Maria Zverina

utilisez la chaîne itertools:

>>> import itertools
>>> list(itertools.chain.from_iterable([(12.2817, 12.2817), (0, 0), (8.52, 8.52)]))
[12.2817, 12.2817, 0, 0, 8.52, 8.52]
7
Charles Beattie
>>> flat_list = []
>>> nested_list = [(1, 2, 4), (0, 9)]
>>> for a_Tuple in nested_list:
...     flat_list.extend(list(a_Tuple))
... 
>>> flat_list
[1, 2, 4, 0, 9]
>>> 

vous pouvez facilement passer de la liste des Tuple à la liste unique comme indiqué ci-dessus.

5
cobie

pdate: Aplatissement en utilisant extend mais sans compréhension et sans utiliser list comme itérateur (le plus rapide)

Après avoir vérifié la réponse suivante, cela a fourni une solution plus rapide via une compréhension de liste avec dual for J'ai fait un petit Tweak et maintenant ça fonctionne mieux, d'abord l'exécution de la liste (...) traînait un gros pourcentage de temps, puis changeait la compréhension d'une liste pour une boucle simple rasée un peu plus aussi.

La nouvelle solution est:

l = []
for row in output: l.extend(row)

Plus âgée:

Aplatissement avec carte/extension:

l = []
list(map(l.extend, output))

Aplatissement avec compréhension de la liste au lieu de la carte

l = []
list(l.extend(row) for row in output)

quelques temps pour une nouvelle extension et l'amélioration obtenue en supprimant simplement la liste (...) pour [...]:

import timeit
t = timeit.timeit
o = "output=list(Zip(range(1000000000), range(10000000))); l=[]"
steps_ext = "for row in output: l.extend(row)"
steps_ext_old = "list(l.extend(row) for row in output)"
steps_ext_remove_list = "[l.extend(row) for row in output]"
steps_com = "[item for sublist in output for item in sublist]"

print("new extend:      ", t(steps_ext, setup=o, number=10))
print("old extend w []: ", t(steps_ext_remove_list, setup=o, number=10))
print("comprehension:   ", t(steps_com, setup=o, number=10,))
print("old extend:      ", t(steps_ext_old, setup=o, number=10))

>>> new extend:       4.502427191007882
>>> old extend w []:  5.281140706967562
>>> comprehension:    5.54302118299529
>>> old extend:       6.840151469223201    
5
Totoro

C'est pour cela que numpy a été conçu, tant du point de vue des structures de données que de la vitesse.

import numpy as np

output = [(12.2817, 12.2817), (0, 0), (8.52, 8.52)]
output_ary = np.array(output)   # this is your matrix 
output_vec = output_ary.ravel() # this is your 1d-array
3
Joshua Cook

En cas de listes imbriquées arbitraires (juste au cas où):

def flatten(lst):
    result = []
    for element in lst: 
        if hasattr(element, '__iter__'):
            result.extend(flatten(element))
        else:
            result.append(element)
    return result

>>> flatten(output)
[12.2817, 12.2817, 0, 0, 8.52, 8.52]
2
cval