Sekliojo sąrašo lyginimas Pythone

Ar yra paprastas būdas supaprastinti iteracijų sąrašą, suprantant sąrašą, arba, jei nenorite į tai atsižvelgti, ką, jūsų manymu, būtų geriausias būdas išlyginti tokį mažą sąrašą, subalansuojant našumą ir suprantamumą?

Bandžiau išlyginti tokį sąrašą naudojant įdėtąjį sąrašą, pavyzdžiui:

 [image for image in menuitem for menuitem in list_of_menuitems] 

Bet aš turiu problemų su NameError veislės, nes name 'menuitem' is not defined . Po „googling“ ir žvelgiant atgal į stekų perpildymą, gaunu norimus rezultatus naudodami reduce nurodymą:

 reduce(list.__add__, map(lambda x: list(x), list_of_menuitems)) 

Tačiau šis metodas yra gana neįveikiamas, nes man reikia skambučio į list(x) , nes x yra Django QuerySet objektas.

Išvada :

Ačiū visiems, kurie prisidėjo prie šio klausimo. Čia yra tai, ką sužinojau, santrauka. Taip pat sukuriu šią wiki bendruomenę, jei kiti nori pridėti ar pataisyti šias pastabas.

Mano originalaus mažinimo instrukcija yra nereikalinga ir geriau parašyta taip:

 >>> reduce(list.__add__, (list(mi) for mi in list_of_menuitems)) 

Tai tinkama įterptųjų sąrašų supratimo sintaksė (Brilliant Summary dF !):

 >>> [image for mi in list_of_menuitems for image in mi] 

Tačiau nė vienas iš šių metodų nėra toks pat veiksmingas kaip naudojant itertools.chain :

 >>> from itertools import chain >>> list(chain(*list_of_menuitems)) 

Ir kaip @cdleary pažymi, tai tikriausiai yra geriausias stilius, kad būtų išvengta * operatoriaus magijos naudojant chain.from_iterable

 >>> chain = itertools.chain.from_iterable([[1,2],[3],[5,89],[],[6]]) >>> print(list(chain)) >>> [1, 2, 3, 5, 89, 6] 
363
02 янв. nustatė Prairiedogg 02 Jan 2009-01-02 08:40 '09 8:40 am 2009-01-02 08:40
@ 23 atsakymai

Jei paprasčiausiai ieškote iteracijos per plokščią duomenų struktūros versiją ir nereikia indeksuotos sekos, apsvarstykite itertools.chain ir įmonę .

 >>> list_of_menuitems = [['image00', 'image01'], ['image10'], []] >>> import itertools >>> chain = itertools.chain(*list_of_menuitems) >>> print(list(chain)) ['image00', 'image01', 'image10'] 

Jis dirbs su bet kokiu iterable, kuris turėtų apimti Django iterable QuerySet s, kuriuos, atrodo, naudojate klausime.

Redaguoti: bet kuriuo atveju tai tikriausiai yra tokia pat gera, kaip sumažinimas, nes sumažinimas turės tą patį pridėtinį, kopijuojant elementus į išplėstinį sąrašą. chain tai padarys (tą patį) pridėtinę vertę, jei pabaigoje vykdysite list(chain) .

Meta-redagavimas: tai iš tikrųjų yra mažesnė nei siūlomo sprendimo pridėtinė pridėtinė vertė, nes jūs išskleidžiate laikinus sąrašus, kuriuos sukuriate, kai išplėsite originalą laikinu.

Redagavimas: Kaip sako JF Sebastianas, kad itertools.chain.from_iterable išvengia išpakavimo, ir jūs turėtumėte tai naudoti, kad būtų išvengta magijos * , tačiau laiko taikymas rodo šiek tiek skirtumą.

279
02 янв. atsakymas duotas cdleary 02 jan. 2009-01-02 09:49 '09, 9:49 AM 2009-01-02 09:49

Jūs beveik turite jį! būdas įterpti įdėtus sąrašus yra pateikti pareiškimams ta pačia tvarka kaip ir įprasta įdėta operacijoms.

Taigi tai

 for inner_list in outer_list: for item in inner_list: ... 

atitinka

 [... for inner_list in outer_list for item in inner_list] 

Taigi jūs norite

 [image for menuitem in list_of_menuitems for image in menuitem] 
259
Atsakymas yra dF. 02 Sau 2009-01-02 11:30 '09 11:30 val. 2009-01-02 11:30

@ S.Lott : Jūs įkvėpėte mane parašyti laiko taikymą.

Supratau, kad tai taip pat pasikeis priklausomai nuo sekcijų skaičiaus (iteratorių skaičius konteinerių sąraše) - jūsų komentare neminima, kiek sekcijų buvo 30 taškų. Šis grafikas prilygsta tūkstantį elementų kiekviename bėgyje su skirtingu sekcijų skaičiumi. Elementai yra tolygiai paskirstyti tarp sekcijų.

Kodas (Python 2.6):

 #!/usr/bin/env python2.6 """Usage: %prog item_count""" from __future__ import print_function import collections import itertools import operator from timeit import Timer import sys import matplotlib.pyplot as pyplot def itertools_flatten(iter_lst): return list(itertools.chain(*iter_lst)) def itertools_iterable_flatten(iter_iter): return list(itertools.chain.from_iterable(iter_iter)) def reduce_flatten(iter_lst): return reduce(operator.add, map(list, iter_lst)) def reduce_lambda_flatten(iter_lst): return reduce(operator.add, map(lambda x: list(x), [i for i in iter_lst])) def comprehension_flatten(iter_lst): return list(item for iter_ in iter_lst for item in iter_) METHODS = ['itertools', 'itertools_iterable', 'reduce', 'reduce_lambda', 'comprehension'] def _time_test_assert(iter_lst): """Make sure all methods produce an equivalent value. :raise AssertionError: On any non-equivalent value.""" callables = (globals()[method + '_flatten'] for method in METHODS) results = [callable(iter_lst) for callable in callables] if not all(result == results[0] for result in results[1:]): raise AssertionError def time_test(partition_count, item_count_per_partition, test_count=10000): """Run flatten methods on a list of :param:`partition_count` iterables. Normalize results over :param:`test_count` runs. :return: Mapping from method to (normalized) microseconds per pass. """ iter_lst = [[dict()] * item_count_per_partition] * partition_count print('Partition count: ', partition_count) print('Items per partition:', item_count_per_partition) _time_test_assert(iter_lst) test_str = 'flatten(%r)' % iter_lst result_by_method = {} for method in METHODS: setup_str = 'from test import %s_flatten as flatten' % method t = Timer(test_str, setup_str) per_pass = test_count * t.timeit(number=test_count) / test_count print('%20s: %.2f usec/pass' % (method, per_pass)) result_by_method[method] = per_pass return result_by_method if __name__ == '__main__': if len(sys.argv) != 2: raise ValueError('Need a number of items to flatten') item_count = int(sys.argv[1]) partition_counts = [] pass_times_by_method = collections.defaultdict(list) for partition_count in xrange(1, item_count): if item_count % partition_count != 0: continue items_per_partition = item_count / partition_count result_by_method = time_test(partition_count, items_per_partition) partition_counts.append(partition_count) for method, result in result_by_method.iteritems(): pass_times_by_method[method].append(result) for method, pass_times in pass_times_by_method.iteritems(): pyplot.plot(partition_counts, pass_times, label=method) pyplot.legend() pyplot.title('Flattening Comparison for %d Items' % item_count) pyplot.xlabel('Number of Partitions') pyplot.ylabel('Microseconds') pyplot.show() 

Redaguoti: buvo nuspręsta padaryti šią wiki bendruomenę.

Pastaba METHODS turbūt turėtų būti kaupiami dekoratoriaus pagalba, bet manau, kad žmonėms būtų lengviau skaityti šį kelią.

125
03 янв. atsakymas duotas cdleary 03 Jan 2009-01-03 02:16 '09, 2:16 am. 2009-01-03 02:16

sum(list_of_lists, []) yra.

 l = [['image00', 'image01'], ['image10'], []] print sum(l,[]) # prints ['image00', 'image01', 'image10'] 
44
27 февр. Prem Anand atsakymas, pateiktas vasario 27 d 2014-02-27 22:03 '14, 10:03 val. 2014-02-27 22:03

Šis sprendimas veikia savavališkai, o ne tik „sąrašų sąrašo“, kuriam kai kurie (visi?), Sąrašas yra ribotas:

 def flatten(x): result = [] for el in x: if hasattr(el, "__iter__") and not isinstance(el, basestring): result.extend(flatten(el)) else: result.append(el) return result 

Tai rekursas, leidžiantis nustatyti savavališką gylį - žinoma, kol pasieksite maksimalų rekursijos gylį.

37
02 янв. James Brady atsakymas dėl sausio 02 d 2009-01-02 16:49 '09, 16:49 PM 2009-01-02 16:49

„Python 2.6“, naudojant chain.from_iterable() :

 >>> from itertools import chain >>> list(chain.from_iterable(mi.image_set.all() for mi in h.get_image_menu())) 

Jis vengia sudaryti tarpinį sąrašą.

23
04 янв. atsakymas pateikiamas jfs 04 jan. 2009-01-04 22:37 '09, 10:37 pm 2009-01-04 22:37

Veiklos rezultatai Perdirbimas

 import itertools def itertools_flatten( aList ): return list( itertools.chain(*aList) ) from operator import add def reduce_flatten1( aList ): return reduce(add, map(lambda x: list(x), [mi for mi in aList])) def reduce_flatten2( aList ): return reduce(list.__add__, map(list, aList)) def comprehension_flatten( aList ): return list(y for x in aList for y in x) 

Aš išlyginau dviejų lygių 30 elementų sąrašą 1000 kartų

 itertools_flatten 0.00554 comprehension_flatten 0.00815 reduce_flatten2 0.01103 reduce_flatten1 0.01404 

Genėjimas visada yra blogas pasirinkimas.

22
02 янв. atsakymas, kurį pateikė S.Lott 2009-01-02 15:13 '09, 15:13, 2009-01-02 15:13

Atrodo, kad operator.add yra nepatogus! Kai kartu pridedate du sąrašus, teisingas terminas yra concat , ne pridėti. operator.concat yra tai, ką jums reikia naudoti.

Jei manote apie funkcionalumą, tai taip paprasta:

 >>> list2d = ((1,2,3),(4,5,6), (7,), (8,9)) >>> reduce(operator.concat, list2d) (1, 2, 3, 4, 5, 6, 7, 8, 9) 

Matote, kad sumažėja pagarba sekos tipui, taigi, pristatydami paketą, grąžinsite paketą. pabandykite sąrašą:

 >>> list2d = [[1,2,3],[4,5,6], [7], [8,9]] >>> reduce(operator.concat, list2d) [1, 2, 3, 4, 5, 6, 7, 8, 9] 

Taip, jūs grįšite sąrašą.

Kaip apie našumą:

 >>> list2d = [[1,2,3],[4,5,6], [7], [8,9]] >>> %timeit list(itertools.chain.from_iterable(list2d)) 1000000 loops, best of 3: 1.36 µs per loop 

from_iterable gana greitai! Tačiau tai nėra palyginimas su sumažėjimu su koncatu.

 >>> list2d = ((1,2,3),(4,5,6), (7,), (8,9)) >>> %timeit reduce(operator.concat, list2d) 1000000 loops, best of 3: 492 ns per loop 
15
07 окт. atsakymą pateikė „ Meitham“ spalis 07 2014-10-07 00:54 '14 prie 0:54 2014-10-07 00:54

Ant galvos galite pašalinti lambda:

 reduce(list.__add__, map(list, [mi.image_set.all() for mi in list_of_menuitems])) 

Arba net pašalinkite žemėlapį, nes jau turite sąrašą-comp:

 reduce(list.__add__, [list(mi.image_set.all()) for mi in list_of_menuitems]) 

Taip pat galite tiesiog išreikšti jį kaip sąrašų sumą:

 sum([list(mi.image_set.all()) for mi in list_of_menuitems], []) 
8
02 янв. atsakymas duotas rekursiniam 02 sausio. 2009-01-02 08:55 '09 8:55 am 2009-01-02 08:55

Čia yra teisingas sprendimas naudojant sąrašus (jie atsilieka nuo klausimo):

 >>> join = lambda it: (y for x in it for y in x) >>> list(join([[1,2],[3,4,5],[]])) [1, 2, 3, 4, 5] 

Jūsų atveju tai bus

 [image for menuitem in list_of_menuitems for image in menuitem.image_set.all()] 

arba galite naudoti join ir pasakyti

 join(menuitem.image_set.all() for menuitem in list_of_menuitems) 

Bet kokiu atveju, gotcha yra kontūrų įdėjimas.

7
02 янв. Josh Lee atsakymas, pateiktas sausio 02 d 2009-01-02 10:33 '09 at 10:33 am 2009-01-02 10:33

Čia yra versija, kuri veikia keliais sąrašo lygiais, naudodama collectons.Iterable .

 import collections def flatten(o, flatten_condition=lambda i: isinstance(i, collections.Iterable) and not isinstance(i, str)): result = [] for i in o: if flatten_condition(i): result.extend(flatten(i, flatten_condition)) else: result.append(i) return result 
4
15 дек. Atsakymas pateikiamas Pierre Thibault 15 d. 2014-12-15 09:03 '14 at 9:03 2014-12-15 09:03

Ši versija yra generatorius. Jei norite sąrašo, tegul tai būtina.

 def list_or_tuple(l): return isinstance(l,(list,tuple)) ## predicate will select the container to be flattened ## write your own as required ## this one flattens every list/tuple def flatten(seq,predicate=list_or_tuple): ## recursive generator for i in seq: if predicate(seq): for j in flatten(i): yield j else: yield i 

Galite pridėti predikato, jei norite išlyginti tas sąlygas, kurios atitinka sąlygą

Paimta iš „python“ virimo knygos

3
23 дек. atsakymas duodamas 23 d. 2013-12-23 12:33 '13, 12:33, 2013-12-23 12:33

Ar bandėte išlyginti? Iš matplotlib.cbook.flatten (seq, scalarp =) ?

 l=[[1,2,3],[4,5,6], [7], [8,9]]*33 run("list(flatten(l))") 3732 function calls (3303 primitive calls) in 0.007 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 0.007 0.007 <string>:1(<module>) 429 0.001 0.000 0.001 0.000 cbook.py:475(iterable) 429 0.002 0.000 0.003 0.000 cbook.py:484(is_string_like) 429 0.002 0.000 0.006 0.000 cbook.py:565(is_scalar_or_string) 727/298 0.001 0.000 0.007 0.000 cbook.py:605(flatten) 429 0.000 0.000 0.001 0.000 core.py:5641(isMaskedArray) 858 0.001 0.000 0.001 0.000 {isinstance} 429 0.000 0.000 0.000 0.000 {iter} 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} l=[[1,2,3],[4,5,6], [7], [8,9]]*66 run("list(flatten(l))") 7461 function calls (6603 primitive calls) in 0.007 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 0.007 0.007 <string>:1(<module>) 858 0.001 0.000 0.001 0.000 cbook.py:475(iterable) 858 0.002 0.000 0.003 0.000 cbook.py:484(is_string_like) 858 0.002 0.000 0.006 0.000 cbook.py:565(is_scalar_or_string) 1453/595 0.001 0.000 0.007 0.000 cbook.py:605(flatten) 858 0.000 0.000 0.001 0.000 core.py:5641(isMaskedArray) 1716 0.001 0.000 0.001 0.000 {isinstance} 858 0.000 0.000 0.000 0.000 {iter} 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} l=[[1,2,3],[4,5,6], [7], [8,9]]*99 run("list(flatten(l))") 11190 function calls (9903 primitive calls) in 0.010 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 0.010 0.010 <string>:1(<module>) 1287 0.002 0.000 0.002 0.000 cbook.py:475(iterable) 1287 0.003 0.000 0.004 0.000 cbook.py:484(is_string_like) 1287 0.002 0.000 0.009 0.000 cbook.py:565(is_scalar_or_string) 2179/892 0.001 0.000 0.010 0.000 cbook.py:605(flatten) 1287 0.001 0.000 0.001 0.000 core.py:5641(isMaskedArray) 2574 0.001 0.000 0.001 0.000 {isinstance} 1287 0.000 0.000 0.000 0.000 {iter} 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} l=[[1,2,3],[4,5,6], [7], [8,9]]*132 run("list(flatten(l))") 14919 function calls (13203 primitive calls) in 0.013 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 0.013 0.013 <string>:1(<module>) 1716 0.002 0.000 0.002 0.000 cbook.py:475(iterable) 1716 0.004 0.000 0.006 0.000 cbook.py:484(is_string_like) 1716 0.003 0.000 0.011 0.000 cbook.py:565(is_scalar_or_string) 2905/1189 0.002 0.000 0.013 0.000 cbook.py:605(flatten) 1716 0.001 0.000 0.001 0.000 core.py:5641(isMaskedArray) 3432 0.001 0.000 0.001 0.000 {isinstance} 1716 0.001 0.000 0.001 0.000 {iter} 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' 

UPDATE Tai suteikė man kitą idėją:

 l=[[1,2,3],[4,5,6], [7], [8,9]]*33 run("flattenlist(l)") 564 function calls (432 primitive calls) in 0.000 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 133/1 0.000 0.000 0.000 0.000 <ipython-input-55-39b139bad497>:4(flattenlist) 1 0.000 0.000 0.000 0.000 <string>:1(<module>) 429 0.000 0.000 0.000 0.000 {isinstance} 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} l=[[1,2,3],[4,5,6], [7], [8,9]]*66 run("flattenlist(l)") 1125 function calls (861 primitive calls) in 0.001 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 265/1 0.001 0.000 0.001 0.001 <ipython-input-55-39b139bad497>:4(flattenlist) 1 0.000 0.000 0.001 0.001 <string>:1(<module>) 858 0.000 0.000 0.000 0.000 {isinstance} 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} l=[[1,2,3],[4,5,6], [7], [8,9]]*99 run("flattenlist(l)") 1686 function calls (1290 primitive calls) in 0.001 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 397/1 0.001 0.000 0.001 0.001 <ipython-input-55-39b139bad497>:4(flattenlist) 1 0.000 0.000 0.001 0.001 <string>:1(<module>) 1287 0.000 0.000 0.000 0.000 {isinstance} 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} l=[[1,2,3],[4,5,6], [7], [8,9]]*132 run("flattenlist(l)") 2247 function calls (1719 primitive calls) in 0.002 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 529/1 0.001 0.000 0.002 0.002 <ipython-input-55-39b139bad497>:4(flattenlist) 1 0.000 0.000 0.002 0.002 <string>:1(<module>) 1716 0.001 0.000 0.001 0.000 {isinstance} 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} l=[[1,2,3],[4,5,6], [7], [8,9]]*1320 run("flattenlist(l)") 22443 function calls (17163 primitive calls) in 0.016 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 5281/1 0.011 0.000 0.016 0.016 <ipython-input-55-39b139bad497>:4(flattenlist) 1 0.000 0.000 0.016 0.016 <string>:1(<module>) 17160 0.005 0.000 0.005 0.000 {isinstance} 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} 

Taigi, norint išbandyti, kaip veiksmingai tai atsitinka, kai rekursyvumas gilėja: kiek giliau?

 l=[[1,2,3],[4,5,6], [7], [8,9]]*1320 new=[l]*33 run("flattenlist(new)") 740589 function calls (566316 primitive calls) in 0.418 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 174274/1 0.281 0.000 0.417 0.417 <ipython-input-55-39b139bad497>:4(flattenlist) 1 0.001 0.001 0.418 0.418 <string>:1(<module>) 566313 0.136 0.000 0.136 0.000 {isinstance} 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} new=[l]*66 run("flattenlist(new)") 1481175 function calls (1132629 primitive calls) in 0.809 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 348547/1 0.542 0.000 0.807 0.807 <ipython-input-55-39b139bad497>:4(flattenlist) 1 0.002 0.002 0.809 0.809 <string>:1(<module>) 1132626 0.266 0.000 0.266 0.000 {isinstance} 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} new=[l]*99 run("flattenlist(new)") 2221761 function calls (1698942 primitive calls) in 1.211 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 522820/1 0.815 0.000 1.208 1.208 <ipython-input-55-39b139bad497>:4(flattenlist) 1 0.002 0.002 1.211 1.211 <string>:1(<module>) 1698939 0.393 0.000 0.393 0.000 {isinstance} 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} new=[l]*132 run("flattenlist(new)") 2962347 function calls (2265255 primitive calls) in 1.630 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 697093/1 1.091 0.000 1.627 1.627 <ipython-input-55-39b139bad497>:4(flattenlist) 1 0.003 0.003 1.630 1.630 <string>:1(<module>) 2265252 0.536 0.000 0.536 0.000 {isinstance} 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} new=[l]*1320 run("flattenlist(new)") 29623443 function calls (22652523 primitive calls) in 16.103 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 6970921/1 10.842 0.000 16.069 16.069 <ipython-input-55-39b139bad497>:4(flattenlist) 1 0.034 0.034 16.103 16.103 <string>:1(<module>) 22652520 5.227 0.000 5.227 0.000 {isinstance} 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} 

Įdėjau „flattenlist“. Aš naudosiu tai vietoj matploblib ilgą laiką, jei nenoriu, kad derliaus generatorius ir greitas rezultatas būtų „išlyginti“ matploblib.cbook

Tai greita.

  • Ir čia yra kodas

:

 typ=(list,tuple) def flattenlist(d): thelist = [] for x in d: if not isinstance(x,typ): thelist += [x] else: thelist += flattenlist(x) return thelist 
3
05 дек. Atsakymą pateikė user2290820 05 Dec. 2013-12-05 15:54 '13, 15:54, 2013-12-05 15:54

Mano patirtis rodo, kad efektyviausias sąrašų sąrašo sklandinimo būdas yra:

 flat_list = [] map(flat_list.extend, list_of_list) 

Kai kurie laiko palyginimai su kitais siūlomais metodais:

 list_of_list = [range(10)]*1000 %timeit flat_list=[]; map(flat_list.extend, list_of_list) #10000 loops, best of 3: 119 µs per loop %timeit flat_list=list(itertools.chain.from_iterable(list_of_list)) #1000 loops, best of 3: 210 µs per loop %timeit flat_list=[i for sublist in list_of_list for i in sublist] #1000 loops, best of 3: 525 µs per loop %timeit flat_list=reduce(list.__add__,list_of_list) #100 loops, best of 3: 18.1 ms per loop 

Dabar, padidėjus abonentų skaičiui, efektyvumo padidėjimas atrodo geriau:

 list_of_list = [range(1000)]*10 %timeit flat_list=[]; map(flat_list.extend, list_of_list) #10000 loops, best of 3: 60.7 µs per loop %timeit flat_list=list(itertools.chain.from_iterable(list_of_list)) #10000 loops, best of 3: 176 µs per loop 

Šie metodai taip pat veikia su bet kokiu iteracijos objektu:

 class SquaredRange(object): def __init__(self, n): self.range = range(n) def __iter__(self): for i in self.range: yield i**2 list_of_list = [SquaredRange(5)]*3 flat_list = [] map(flat_list.extend, list_of_list) print flat_list #[0, 1, 4, 9, 16, 0, 1, 4, 9, 16, 0, 1, 4, 9, 16] 
3
20 янв. Atsakymą pateikė Juh_ Jan 20 2014-01-20 18:19 '14, 18:19, 2014-01-20 18:19

Kaip apie:

 from operator import add reduce(add, map(lambda x: list(x.image_set.all()), [mi for mi in list_of_menuitems])) 

Tačiau „Guido“ rekomenduoja neveikti pernelyg daug vienos kodo eilutės, nes tai sumažina skaitomumą. Yra minimalus, jei įmanoma, našumo padidinimas, darant tai, ko norite vienoje eilutėje ar keliose eilutėse.

2
02 янв. atsakymas danielis 02 jan. 2009-01-02 09:28 '09, 9:28 am. 2009-01-02 09:28

Jei ieškote įmontuoto, paprasto, vienos eilutės, galite naudoti:

 a = [[1, 2, 3], [4, 5, 6] b = [i[x] for i in a for x in range(len(i))] print b 

grąžina

 [1, 2, 3, 4, 5, 6] 
2
27 авг. Bottersnike atsakė 27 rugpjūčio mėn. 2015-08-27 18:39 '15, 18:39, 2015-08-27 18:39

Jei jums reikia sukurti sudėtingesnį sąrašą su ne kartojamais elementais arba daugiau nei 2 gylį, galite naudoti šią funkciją:

 def flat_list(list_to_flat): if not isinstance(list_to_flat, list): yield list_to_flat else: for item in list_to_flat: yield from flat_list(item) 

Jis grąžins generatoriaus objektą, kurį galite konvertuoti į sąrašą, naudodami list() funkciją. Atkreipkite dėmesį, kad sintaksės yield from pradedant python3.3, bet vietoj to galite naudoti aiškų iteraciją.
Pavyzdys:

 >>> a = [1, [2, 3], [1, [2, 3, [1, [2, 3]]]]] >>> print(list(flat_list(a))) [1, 2, 3, 1, 2, 3, 1, 2, 3] 
2
12 апр. DartLenino atsakymas, pateiktas balandžio 12 d 2015-04-12 04:05 '15, 04:05 2015-04-12 04:05
 def flatten(items): for i in items: if hasattr(i, '__iter__'): for m in flatten(i): yield m else: yield i 

Bandymas:

 print list(flatten2([1.0, 2, 'a', (4,), ((6,), (8,)), (((8,),(9,)), ((12,),(10)))])) 
2
05 апр. atsakymas pateikiamas kopos 05 Bal 2016-04-05 16:28 '16, 16:28 pm 2016-04-05 16:28

„pylab“ suteikia anti-aliasing: nuoroda į numpy flatten

2
22 февр. Atsakymas pateikiamas vasario 22 d 2014-02-22 20:01 '14, 20:01, 2014-02-22 20:01

Paprasta alternatyva yra naudoti numpy concatenate , tačiau jis konvertuoja turinį į plaukti:

 import numpy as np print np.concatenate([[1,2],[3],[5,89],[],[6]]) # array([ 1., 2., 3., 5., 89., 6.]) print list(np.concatenate([[1,2],[3],[5,89],[],[6]])) # [ 1., 2., 3., 5., 89., 6.] 
1
14 окт. atsakymas pateikiamas strpeter 14 oct. 2015-10-14 11:29 '15 at 11:29 2015-10-14 11:29

Jei kiekvienas sąrašo elementas yra eilutė (ir visos eilutės viduje šiose eilutėse naudoja „, bet ne“), galite naudoti įprastas išraiškas ( re modulis)

 >>> flattener = re.compile("\'.*?\'") >>> flattener <_sre.SRE_Pattern object at 0x10d439ca8> >>> stred = str(in_list) >>> outed = flattener.findall(stred) 

Anksčiau minėtas kodas konvertuoja in_list į eilutę, naudoja įprastą išraišką, kad surastų visus kabučių viduje esančius tekstus (ty kiekvieną elementą sąraše) ir juos išskleistų kaip sąrašą.

1
03 дек. atsakymas, kurį pateikė user22723 03 dec. 2014-12-03 23:06 '14 ne 23:06 2014-12-03 23:06

Paprasčiausias būdas tai padaryti 2 arba 3 „Python“ yra naudoti „ morph“ biblioteką naudojant „ pip install morph .

Kodas:

 import morph list = [[1,2],[3],[5,89],[],[6]] flattened_list = morph.flatten(list) # returns [1, 2, 3, 5, 89, 6] 
1
15 дек. Atsakymas pateikiamas YPCrumble 15 d. 2015-12-15 23:00 '15 val. 11 val. 2015-12-15 23:00

Python 3.4“ galite:

 [*innerlist for innerlist in outer_list] 
0
27 сент. atsakymas pateikiamas elyase 27 sep . 2013-09-27 17:42 '13, 17:42 2013-09-27 17:42

Kiti klausimai apie „ arba klausimo pateikimas