ලැයිස්තු ලැයිස්තුවෙන් පැතලි ලැයිස්තුවක් සාදා ගන්නේ කෙසේද?


3396

පයිතන් හි ලැයිස්තු ලැයිස්තුවෙන් සරල ලැයිස්තුවක් සෑදීමට කෙටිමඟක් තිබේදැයි මම කල්පනා කරමි.

මට එය forලූපයකින් කළ හැකිය , නමුත් සමහර විට සිසිල් "එක්-ලයිනර්" එකක් තිබේද? මම එය සමඟ උත්සාහ කළ reduce()නමුත් මට දෝෂයක් ඇතිවිය.

කේතය

l = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]
reduce(lambda x, y: x.extend(y), l)

දෝෂ පණිවිඩය

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <lambda>
AttributeError: 'NoneType' object has no attribute 'extend'

20
මෙහි ගැඹුරු සාකච්ඡාවක් ඇත: rightfootin.blogspot.com/2006/09/more-on-python-flatten.html , අත්තනෝමතික ලෙස කැදැලි ලැයිස්තු ලැයිස්තු පැතලි කිරීමේ ක්‍රම කිහිපයක් සාකච්ඡා කරයි. රසවත් කියවීමක්!
රිචී හින්ඩ්ල්

6
තවත් සමහර පිළිතුරු වඩා හොඳ නමුත් ඔබේ පිළිතුර අසමත් වීමට හේතුව 'දීර් extend කිරීමේ' ක්‍රමය සෑම විටම කිසිවක් නොලැබීමයි. දිග 2 සහිත ලැයිස්තුවක් සඳහා, එය ක්‍රියාත්මක වන නමුත් කිසිවක් ආපසු ලබා නොදේ. දිගු ලැයිස්තුවක් සඳහා, එය පළමු ආරුක්කු 2 පරිභෝජනය කරයි, එය කිසිවක් ලබා නොදේ. එය පසුව No.extend (<තෙවන arg>) සමඟ ඉදිරියට යන අතර එමඟින් මෙම දෝෂය ඇති වේ
mehtunguh

@ ෂෝන්-චින් ද්‍රාවණය මෙහි වඩා පයිතොනික් වේ, නමුත් ඔබට අනුක්‍රමික වර්ගය ආරක්ෂා කර ගැනීමට අවශ්‍ය නම්, ඔබට ලැයිස්තු ලැයිස්තුවකට වඩා ටුපල් එකක් ඇති බව පවසන්න, එවිට ඔබ අඩු කිරීම භාවිතා කළ යුතුය (operator.concat, tuple_of_tuples). ක්‍රියාකරු.කොන්කැට් ටුපල් සමඟ භාවිතා කිරීම ලැයිස්තුවක් සහිත දාම.ෆ්‍රොම්_අයිටරබල් වලට වඩා වේගයෙන් ක්‍රියාත්මක වන බව පෙනේ.
මීතම්

Answers:


4818

ලැයිස්තු ලැයිස්තුවක් ලබා දී ඇත l,

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

ඒ කියන්නේ:

flat_list = []
for sublist in l:
    for item in sublist:
        flat_list.append(item)

මෙතෙක් පළ කර ඇති කෙටිමං වලට වඩා වේගවත්ය. ( lසමතලා කළ යුතු ලැයිස්තුවයි.)

අනුරූප ශ්‍රිතය මෙන්න:

flatten = lambda l: [item for sublist in l for item in sublist]

සාක්ෂි ලෙස, ඔබට timeitසම්මත පුස්තකාලයේ මොඩියුලය භාවිතා කළ හැකිය :

$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' '[item for sublist in l for item in sublist]'
10000 loops, best of 3: 143 usec per loop
$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'sum(l, [])'
1000 loops, best of 3: 969 usec per loop
$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'reduce(lambda x,y: x+y,l)'
1000 loops, best of 3: 1.1 msec per loop

පැහැදිලි කිරීම: L උප ලැයිස්තු ඇති විට +( මත පදනම් වූ භාවිතය ඇතුළුව) මත පදනම් වූ කෙටිමං sumඅවශ්‍ය O(L**2)වේ - අතරමැදි ප්‍රති result ල ලැයිස්තුව දිගින් දිගටම පවතින බැවින්, සෑම පියවරකදීම නව අතරමැදි ප්‍රති result ල ලැයිස්තු වස්තුවක් වෙන් කරනු ලැබේ, සහ සියලු අයිතම පෙර අතරමැදි ප්‍රති result ලය පිටපත් කළ යුතුය (මෙන්ම අවසානයේ එකතු කළ නව ඒවා කිහිපයක්). එබැවින්, සරල බව සහ සාමාන්‍යත්වය නැතිවීමකින් තොරව, ඔබට එක් අයිතමයක L උප ලැයිස්තු ඇති බව පවසන්න: පළමු I අයිතම L-1 වතාවක් පෙරළා පිටපත් කරනු ලැබේ, දෙවන I අයිතම L-2 වතාවක් යනාදිය; මුළු පිටපත් ගණන 1 සිට L දක්වා x සඳහා x හි එකතුව මෙන් 1 ගුණයක් වේ, එනම්,I * (L**2)/2 .

ලැයිස්තු අවබෝධය එක් වරකට එක් ලැයිස්තුවක් ජනනය කරන අතර එක් එක් අයිතමය පිටපත් කරයි (එහි මුල් වාසස්ථානයේ සිට ප්‍රති result ල ලැයිස්තුව දක්වා) හරියටම එක් වරක්.


487
මම භාවිතා කරමින් එකම දත්ත සමඟ පරීක්ෂණයක් කිරීමට උත්සාහ කළෙමි itertools.chain.from_iterable: $ python -mtimeit -s'from itertools import chain; l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'list(chain.from_iterable(l))'. මෙහි පෙන්වා ඇති විකල්පයන්ගෙන් වේගවත්ම කැදැලි ලැයිස්තු අවබෝධය මෙන් දෙගුණයකටත් වඩා වේගයෙන් ධාවනය වේ.
intuited

274
ඔබට එය හරියටම ලූප සඳහා කැදැල්ලක් මෙන් සිතිය හැකි බව මට වැටහෙන තුරු සින්ටැක්ස් තේරුම් ගැනීමට අපහසු විය. l හි උප ලැයිස්තු සඳහා: උප ලැයිස්තුවේ ඇති අයිතමය සඳහා: අස්වැන්න අයිතමය
රොබ්

23
Or බොරිස්චර්වෙන්කොව්: මම ඇමතුම ඔතා ඇති බව සැලකිල්ලට ගන්න list().
බුද්ධිමත්

163
[ගසේ කොළ සඳහා වනාන්තරයේ කොළ] තේරුම් ගැනීමට සහ අදාළ කර ගැනීමට පහසු විය හැකිය.
ජෝන් මී

80
O ජොයෙල්, ඇත්ත වශයෙන්ම වර්තමානයේ list(itertools.chain.from_iterable(l))හොඳම වේ - වෙනත් අදහස් සහ ෂෝන්ගේ පිළිතුරෙහි දැක්වෙන පරිදි.
ඇලෙක්ස් මාටෙලි

1577

ඔබට භාවිතා කළ හැකිය itertools.chain():

import itertools
list2d = [[1,2,3], [4,5,6], [7], [8,9]]
merged = list(itertools.chain(*list2d))

නැතහොත් ක්‍රියාකරුitertools.chain.from_iterable() සමඟ ලැයිස්තුව ඉවත් කිරීම අවශ්‍ය නොවන ඔබට භාවිතා කළ හැකිය :*

import itertools
list2d = [[1,2,3], [4,5,6], [7], [8,9]]
merged = list(itertools.chain.from_iterable(list2d))

13
මෙම *කරයි බව කිසිම දෙයක් වේ chainලැයිස්තුව අවබෝධය වඩා අඩු පහසු වේ. දම්වැල පරාමිතීන් ලෙස සම්මත කර ඇති අනුකලනයන් එකට එකතු වන බව ඔබ දැන සිටිය යුතු අතර, * ඉහළ මට්ටමේ ලැයිස්තුව පරාමිතීන් දක්වා පුළුල් කිරීමට හේතු වේ, එබැවින් chainඑම සියලු ක්‍රියාකාරකම් එකට එකතු වේ, නමුත් තවදුරටත් බැස නොයයි. මෙම අවස්ථාවේ දී දාමය භාවිතා කිරීමට වඩා අවබෝධය මෙය කියවිය හැකි යැයි මම සිතමි.
ටිම් ඩියර්ක්ස්

53
ImTimDierks: "මෙය ඔබට පයිතන් සින්ටැක්ස් තේරුම් ගැනීමට අවශ්‍ය වේ" යන්න පයිතන් හි දී ඇති තාක්‍ෂණයක් භාවිතා කිරීමට එරෙහි තර්කයක් බව මට විශ්වාස නැත. නිසැකවම, සංකීර්ණ භාවිතය ව්‍යාකූල විය හැකි නමුත් “ස්ප්ලැට්” ක්‍රියාකරු බොහෝ අවස්ථාවන්හිදී සාමාන්‍යයෙන් ප්‍රයෝජනවත් වන අතර මෙය විශේෂයෙන් අපැහැදිලි ආකාරයකින් භාවිතා නොකරයි; ආරම්භක පරිශීලකයින්ට අනිවාර්යයෙන්ම නොපෙනෙන සියලුම භාෂා අංග ප්‍රතික්ෂේප කිරීම යන්නෙන් අදහස් වන්නේ ඔබ එක් අතක් ඔබේ පිටුපස බැඳ තබන බවයි. ඔබ එහි සිටින විට ලැයිස්තු අවබෝධය ද ඉවත දැමිය හැකිය; වෙනත් පසුබිම්වල පරිශීලකයින්ට forනැවත නැවතත් appendවඩාත් පැහැදිලිව පෙනෙන ලූපයක් සොයාගත හැකිය .
ෂැඩෝ රේන්ජර්

ඉහළ මට්ටමේ ද වටිනාකමක් තිබේ නම් මෙම පිළිතුර සහ මෙහි ඇති වෙනත් පිළිතුරු වැරදි ප්‍රති result ල ලබා දේ. උදාහරණයක් වශයෙන්, list = [["abc","bcd"],["cde","def"],"efg"]නිමැවුම් හේතු වනු ඇත["abc", "bcd", "cde", "def", "e", "f", "g"].
gouravkr

*Python2
wkm

911

කතුවරයාගේ සටහන : මෙය අකාර්යක්ෂමයි. නමුත් විනෝදජනකයි, මොනෝයිඩ් නියමයි. පයිතන් කේතය නිෂ්පාදනය සඳහා එය සුදුසු නොවේ.

>>> sum(l, [])
[1, 2, 3, 4, 5, 6, 7, 8, 9]

මෙය පළමු තර්කයේ සම්මත කළ හැකි මූලද්‍රව්‍යයන් සාරාංශ කරයි, දෙවන තර්කය එකතුවෙහි ආරම්භක අගය ලෙස සලකයි (ලබා නොදුනහොත්, 0 ඒ වෙනුවට භාවිතා වන අතර මෙම නඩුව ඔබට දෝෂයක් ලබා දෙනු ඇත).

ඔබ පිළිතුරු පැතැලිව ලැයිස්තු සාරාංශගත කරමින් සිටින නිසා, ඇත්ත වශයෙන්ම ඔබ ලබා [1,3]+[2,4]ප්රතිඵලයක් ලෙස sum([[1,3],[2,4]],[])සමාන වන,[1,3,2,4] .

ලැයිස්තු වල පමණක් ක්‍රියාත්මක වන බව සලකන්න. ලැයිස්තු ලැයිස්තුවක් සඳහා, ඔබට තවත් විසඳුමක් අවශ්‍ය වේ.


100
එය ඉතා පිළිවෙලට හා දක්ෂ නමුත් කියවීමට අවුල් සහගත බැවින් මම එය භාවිතා නොකරමි.
andrewrk

87
මෙය ෂෙල්මියෙල් චිත්‍ර ශිල්පියාගේ ඇල්ගොරිතම joelonsoftware.com/articles/fog0000000319.html - අනවශ්‍ය ලෙස අකාර්යක්ෂම මෙන්ම අනවශ්‍ය ලෙස කැතයි.
මයික් ග්‍රැහැම්

44
ලැයිස්තු වල උපග්‍රන්ථ මෙහෙයුම a සාදයි Monoid, එය +සාමාන්‍ය අර්ථයෙන් මෙහෙයුමක් ගැන සිතීම සඳහා වඩාත් පහසු වියුක්තයකි (අංකවලට පමණක් සීමා නොවේ). එබැවින් මෙම පිළිතුර ලැයිස්තුවක් මොනොයිඩයක් ලෙස සැලකීම සඳහා (නිවැරදි) මගෙන් +1 ලැබිය යුතුය. කාර්ය සාධනය කෙසේ වෙතත් ...
ulidtko

7
reandrewrk හොඳයි, සමහර අය සිතන්නේ මෙය කළ හැකි පිරිසිදුම ක්‍රමය මෙයයි: youtube.com/watch?v=IOiZatlZtGU මෙය සිසිල් වන්නේ ඇයිදැයි නොදන්නා අය සෑම කෙනෙකුම මේ ආකාරයට කරන තුරු දශක කිහිපයක් බලා සිටිය යුතුය: ) සොයාගත් හා සොයා නොගත් ක්‍රමලේඛන භාෂා (සහ වියුක්ත) භාවිතා කරමු, මොනොයිඩ් සොයා ගනු ලැබේ.
ජෙගෙඩස්

11
එකතුවෙහි චතුරස්රාකාර අංගය නිසා මෙය ඉතා අකාර්යක්ෂම ක්‍රමයකි.
ජීන්-ප්‍රංශුවා ෆැබ්රේ

464

මම බොහෝ යෝජනා විසඳුම් පරීක්ෂා perfplot (මගේ සුරතල් ව්යාපෘතිය, පමණ, අවශ්යයෙන්ම දවටනය timeit), සහ සොයා ගත්

functools.reduce(operator.iconcat, a, [])

බොහෝ කුඩා ලැයිස්තු සහ දිගු ලැයිස්තු කිහිපයක් සමපාත වන විට වේගවත්ම විසඳුම වනු ඇත. ( operator.iaddසමානව වේගවත් වේ.)

රූප විස්තරය මෙහි ඇතුළත් කරන්න

රූප විස්තරය මෙහි ඇතුළත් කරන්න


කුමන්ත්රණය ප්රතිනිෂ්පාදනය කිරීමේ කේතය:

import functools
import itertools
import numpy
import operator
import perfplot


def forfor(a):
    return [item for sublist in a for item in sublist]


def sum_brackets(a):
    return sum(a, [])


def functools_reduce(a):
    return functools.reduce(operator.concat, a)


def functools_reduce_iconcat(a):
    return functools.reduce(operator.iconcat, a, [])


def itertools_chain(a):
    return list(itertools.chain.from_iterable(a))


def numpy_flat(a):
    return list(numpy.array(a).flat)


def numpy_concatenate(a):
    return list(numpy.concatenate(a))


perfplot.show(
    setup=lambda n: [list(range(10))] * n,
    # setup=lambda n: [list(range(n))] * 10,
    kernels=[
        forfor,
        sum_brackets,
        functools_reduce,
        functools_reduce_iconcat,
        itertools_chain,
        numpy_flat,
        numpy_concatenate,
    ],
    n_range=[2 ** k for k in range(16)],
    xlabel="num lists (of length 10)",
    # xlabel="len lists (10 lists total)"
)

25
දැවැන්ත කැදැලි ලැයිස්තු සඳහා, 'list (numpy.array (a) .flat)' යනු ඉහත සියළු කාර්යයන් අතර වේගවත්ම වේ.
සාරා

Regex භාවිතා කිරීමට උත්සාහ කර ඇත: 'ලැයිස්තුව (සිතියම (int, re.findall (r "[\ w] +", str (a)))'. අංකප_කොන්කේටනේට් වේගය ටිකක් මන්දගාමී වේ
ජස්ටාස්

3-d perfplot කිරීමට ක්‍රමයක් තිබේද? අරාවෙහි සාමාන්‍ය ප්‍රමාණය අනුව අරා ගණන?
ලියෝ

මම ඔබේ විසඳුමට කැමතියි. කෙටි, සරල හා කාර්යක්ෂම :-)
චැඩී ෆවුඩ්

නියම ප්‍රස්තාරය, ඔබේ කාර්යයට ආදරය කරන්න!
CpILL

182
from functools import reduce #python 3

>>> l = [[1,2,3],[4,5,6], [7], [8,9]]
>>> reduce(lambda x,y: x+y,l)
[1, 2, 3, 4, 5, 6, 7, 8, 9]

extend()ඔබේ උදාහරණයේ ඇති ක්‍රමය xප්‍රයෝජනවත් අගයක් ලබා දීම වෙනුවට වෙනස් කරයි (එය reduce()අපේක්ෂා කරයි).

reduceඅනුවාදය කිරීමට වේගවත් ක්‍රමයක් වනු ඇත

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

20
reduce(operator.add, l)reduceඅනුවාදය කිරීමට නිවැරදි ක්‍රමය වනු ඇත . බිල්ට් ලැම්බඩා වලට වඩා වේගවත්ය.
agf

3
@agf මෙන්න: * timeit.timeit('reduce(operator.add, l)', 'import operator; l=[[1, 2, 3], [4, 5, 6, 7, 8], [1, 2, 3, 4, 5, 6, 7]]', number=10000) 0.017956018447875977 * timeit.timeit('reduce(lambda x, y: x+y, l)', 'import operator; l=[[1, 2, 3], [4, 5, 6, 7, 8], [1, 2, 3, 4, 5, 6, 7]]', number=10000) 0.025218963623046875
lukmdo

8
මෙය ෂෙල්මියෙල් චිත්‍ර ශිල්පියාගේ ඇල්ගොරිතම joelonsoftware.com/articles/fog0000000319.html
මයික් ග්‍රැහැම්

2
මෙය භාවිතා කළ හැක්කේ සඳහා පමණි integers. නමුත් ලැයිස්තුවේ තිබේ නම් කුමක් කළ stringයුතුද?
ෆ්‍රෙඩී

3
Red ෆ්‍රෙඩී: operator.addශ්‍රිතය පූර්ණ සංඛ්‍යා ලැයිස්තුවට සහ නූල් ලැයිස්තුවට සමානව ක්‍රියා කරයි.
ග්‍රෙග් හෙව්ගිල්

122

ඔබ ජැන්ගෝ භාවිතා කරන්නේ නම් රෝදය ප්‍රතිනිර්මාණය නොකරන්න :

>>> from django.contrib.admin.utils import flatten
>>> l = [[1,2,3], [4,5], [6]]
>>> flatten(l)
>>> [1, 2, 3, 4, 5, 6]

... පණ්ඩස් :

>>> from pandas.core.common import flatten
>>> list(flatten(l))

... ඉටර්ටූල්ස් :

>>> import itertools
>>> flatten = itertools.chain.from_iterable
>>> list(flatten(l))

... මැට්ප්ලොට්ලිබ්

>>> from matplotlib.cbook import flatten
>>> list(flatten(l))

... යුනිපාත් :

>>> from unipath.path import flatten
>>> list(flatten(l))

... සැකසුම් :

>>> from setuptools.namespaces import flatten
>>> list(flatten(l))

4
flatten = itertools.chain.from_iterableනිවැරදි පිළිතුර විය යුතුය
හූනන්

3
නියම පිළිතුර! පැන්ඩා සම්බන්ධයෙන් l = [[[1, 2, 3], [4, 5], 5] සඳහාද ක්‍රියා කරයි
මාකස් ඩට්ෂ්කේ

1
මම පැන්ඩස් විසඳුමට කැමතියි. ඔබට එවැනි දෙයක් තිබේ නම්:, list_of_menuitems = [1, 2, [3, [4, 5, [6]]]]එහි ප්‍රති result ලය වනු ඇත්තේ : [1, 2, 3, 4, 5, 6]. මට මග හැරී ඇත්තේ සමතලා මට්ටමයි.
imjoseangel

115

අංක , නූල් , කැදැලි ලැයිස්තු සහ මිශ්‍ර බහාලුම් සඳහා අදාළ වන පොදු ප්‍රවේශයක් මෙන්න .

කේතය

#from typing import Iterable 
from collections import Iterable                            # < py38


def flatten(items):
    """Yield items from any nested iterable; see Reference."""
    for x in items:
        if isinstance(x, Iterable) and not isinstance(x, (str, bytes)):
            for sub_x in flatten(x):
                yield sub_x
        else:
            yield x

සටහන් :

  • පයිතන් 3 හි, yield from flatten(x)ප්රතිස්ථාපනය කළ හැකියfor sub_x in flatten(x): yield sub_x
  • Python 3.8 දී, වියුක්ත පදනම පංති ඇත ගියා සිට collection.abcවෙත typingමොඩියුලය.

නිරූපණය

lst = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]
list(flatten(lst))                                         # nested lists
# [1, 2, 3, 4, 5, 6, 7, 8, 9]

mixed = [[1, [2]], (3, 4, {5, 6}, 7), 8, "9"]              # numbers, strs, nested & mixed
list(flatten(mixed))
# [1, 2, 3, 4, 5, 6, 7, 8, '9']

යොමුව

  • මෙම විසඳුම බීස්ලි, ඩී සහ බී. ජෝන්ස් හි වට්ටෝරුවකින් වෙනස් කර ඇත . වට්ටෝරුව 4.14, පයිතන් කුක්බුක් 3 වන සංස්කරණය, ඕ'රෙයිලි මීඩියා ඉන්කෝපරේෂන් සෙබස්ටොපෝල්, සීඒ: 2013.
  • කලින් SO පෝස්ට් එකක් හමු විය , සමහර විට මුල් නිරූපණය විය හැකිය.

5
මම ඔබේ විසඳුම නොදැක්ක නිසා මම එයම ලිව්වෙමි ... මෙන්න මම "පුනරාවර්තන ලෙස සම්පූර්ණ බහු ලැයිස්තු"
මාටින් තෝමා

3
Art මාර්ටින් තෝමා බොහෝ අගය කළා. FYI, කැදැලි නැවත සකස් කිරීම ඔබට සාමාන්‍ය සිරිතක් නම්, මෙය හොඳින් හසුරුවන තෙවන පාර්ශවීය පැකේජ තිබේ. මෙය රෝදය ප්‍රතිනිර්මාණය කිරීමෙන් ඉතිරි වේ. more_itertoolsමෙම ලිපියේ සාකච්ඡා කර ඇති අනෙක් අය අතර මම සඳහන් කර ඇත්තෙමි . චියර්ස්.
pylang

සමහර විට traverseගසක මෙම ක්‍රමයට හොඳ නමක් ද විය හැකි අතර, කූඩු ලැයිස්තු වලට ඇලී සිටීමෙන් මෙම පිළිතුර සඳහා මම එය විශ්වීය ලෙස අඩු කරමි .
වුල්ෆ්

if hasattr(x, '__iter__')ආනයනය කිරීම / පරීක්ෂා කිරීම වෙනුවට ඔබට පරීක්ෂා කළ හැකි Iterableඅතර එමඟින් නූල්ද බැහැර වේ.
රයන් ඇලන්

කැදැලි ලැයිස්තුවෙන් එකක් නූල් ලැයිස්තුවක් තිබේ නම් ඉහත කේතය ක්‍රියාත්මක වන බවක් නොපෙනේ. [1, 2, [3, 4], [4], [], 9, 9.5, 'ssssss', ['str', 'sss', 'ss'], [3, 4, 5]] ප්‍රතිදානය: - [1, 2, 3, 4, 4, 9, 9.5, 'ssssss', 3, 4, 5]
sunnyX

52

දත්ත ව්‍යුහයක් සමතලා කිරීමට ඔබට අවශ්‍ය නම් එය කොතරම් ගැඹුරට කැදැල්ලක් දැයි ඔබ නොදන්නේ නම් ඔබට 1 භාවිතා කළ හැකියiteration_utilities.deepflatten

>>> from iteration_utilities import deepflatten

>>> l = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]
>>> list(deepflatten(l, depth=1))
[1, 2, 3, 4, 5, 6, 7, 8, 9]

>>> l = [[1, 2, 3], [4, [5, 6]], 7, [8, 9]]
>>> list(deepflatten(l))
[1, 2, 3, 4, 5, 6, 7, 8, 9]

එය උත්පාදක යන්ත්රයක් වන බැවින් ඔබට ප්රති result listලය ඒ මතට දැමිය යුතුය.


එක් මට්ටමක් පමණක් සමතලා කිරීම සඳහා සහ සෑම අයිතමයක්ම නැවත ක්‍රියාත්මක කළ හැකි නම් ඔබට iteration_utilities.flattenවටා තුනී එතීමක් පමණක් භාවිතා කළ හැකිය itertools.chain.from_iterable:

>>> from iteration_utilities import flatten
>>> l = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]
>>> list(flatten(l))
[1, 2, 3, 4, 5, 6, 7, 8, 9]

සමහර වේලාවන් එකතු කිරීම සඳහා (මෙම පිළිතුරෙහි ඉදිරිපත් කර ඇති ශ්‍රිතය ඇතුළත් නොවූ නිකෝ ෂ්ලමර් පිළිතුර මත පදනම්ව):

රූප විස්තරය මෙහි ඇතුළත් කරන්න

විශාල පරාසයක විහිදුණු අගයන් සඳහා ඉඩ සැලසීමට එය ලොග්-ලොග් කුමන්ත්‍රණයකි. ගුණාත්මක තර්කනය සඳහා: පහළ වඩා හොඳය.

ප්‍රති results ල වලින් පෙනී යන්නේ, අනුකාරකයේ අඩංගු වන්නේ අභ්‍යන්තර පුනරාවර්තන කිහිපයක් පමණක් නම් sum එය වේගවත් වනු ඇත, කෙසේ වෙතත් දිගු පුනරාවර්තන සඳහා පමණක් itertools.chain.from_iterable, iteration_utilities.deepflattenහෝ කැදැලි අවබෝධය itertools.chain.from_iterableවේගවත්ම වීමත් සමඟ සාධාරණ කාර්ය සාධනයක් ඇත (දැනටමත් නිකෝ ෂ්ලමර් විසින් දැක ඇති පරිදි).

from itertools import chain
from functools import reduce
from collections import Iterable  # or from collections.abc import Iterable
import operator
from iteration_utilities import deepflatten

def nested_list_comprehension(lsts):
    return [item for sublist in lsts for item in sublist]

def itertools_chain_from_iterable(lsts):
    return list(chain.from_iterable(lsts))

def pythons_sum(lsts):
    return sum(lsts, [])

def reduce_add(lsts):
    return reduce(lambda x, y: x + y, lsts)

def pylangs_flatten(lsts):
    return list(flatten(lsts))

def flatten(items):
    """Yield items from any nested iterable; see REF."""
    for x in items:
        if isinstance(x, Iterable) and not isinstance(x, (str, bytes)):
            yield from flatten(x)
        else:
            yield x

def reduce_concat(lsts):
    return reduce(operator.concat, lsts)

def iteration_utilities_deepflatten(lsts):
    return list(deepflatten(lsts, depth=1))


from simple_benchmark import benchmark

b = benchmark(
    [nested_list_comprehension, itertools_chain_from_iterable, pythons_sum, reduce_add,
     pylangs_flatten, reduce_concat, iteration_utilities_deepflatten],
    arguments={2**i: [[0]*5]*(2**i) for i in range(1, 13)},
    argument_name='number of inner lists'
)

b.plot()

වියාචනය: මම එම පුස්තකාලයේ කර්තෘ වෙමි


sumඑය ආරම්භ වන විට අත්තනෝමතික අනුපිළිවෙලවල් මත තවදුරටත් ක්‍රියාත්මක නොවන 0අතර functools.reduce(operator.add, sequences)එය ප්‍රතිස්ථාපනය කරයි (ඒවා reduceබිල්ඩින් වලින් ඉවත් කිරීම ගැන අපට සතුටු නැද්ද?). වර්ග දන්නා විට එය භාවිතා කිරීම වේගවත් විය හැකිය type.__add__.
යාන් වර්නියර්

AnnYannVernier තොරතුරු වලට ස්තූතියි. මම හිතුවා මම මේ මිණුම් සලකුණු පයිතන් 3.6 මත ධාවනය කළ අතර එය සමඟ වැඩ කළා sum. කුමන පයිතන් අනුවාදයන් වැඩ කිරීම නැවැත්වූවාදැයි ඔබ දැන ගන්නේද?
MSeifert

මම තරමක් වැරදියට තේරුම් ගත්තා. 0සුපුරුදු ආරම්භක අගය පමණක් වන බැවින් හිස් ලැයිස්තුවක් සමඟ ආරම්භ කිරීම සඳහා ආරම්භක තර්කය භාවිතා කරන්නේ නම් එය ක්‍රියාත්මක වේ ... නමුත් එය තවමත් විශේෂ අවස්ථා නූල් වන අතර මට සම්බන්ධ වීමට භාවිතා කරන ලෙස පවසයි. එය foldlවෙනුවට ක්‍රියාත්මක වේ foldl1. එම ප්‍රශ්නයම 2.7 හි මතු වේ.
යාන් වර්නියර්

39

මම මගේ ප්‍රකාශය ආපසු ගන්නෙමි. එකතුව ජයග්‍රාහකයා නොවේ. ලැයිස්තුව කුඩා වන විට එය වේගවත් වුවද. නමුත් විශාල ලැයිස්තු සමඟ කාර්ය සාධනය සැලකිය යුතු ලෙස පිරිහී යයි.

>>> timeit.Timer(
        '[item for sublist in l for item in sublist]',
        'l=[[1, 2, 3], [4, 5, 6, 7, 8], [1, 2, 3, 4, 5, 6, 7]] * 10000'
    ).timeit(100)
2.0440959930419922

එකතුව අනුවාදය තවමත් විනාඩියකට වඩා වැඩි කාලයක් ක්‍රියාත්මක වන අතර එය තවමත් සැකසුම් කර නැත!

මධ්‍යම ලැයිස්තු සඳහා:

>>> timeit.Timer(
        '[item for sublist in l for item in sublist]',
        'l=[[1, 2, 3], [4, 5, 6, 7, 8], [1, 2, 3, 4, 5, 6, 7]] * 10'
    ).timeit()
20.126545906066895
>>> timeit.Timer(
        'reduce(lambda x,y: x+y,l)',
        'l=[[1, 2, 3], [4, 5, 6, 7, 8], [1, 2, 3, 4, 5, 6, 7]] * 10'
    ).timeit()
22.242258071899414
>>> timeit.Timer(
        'sum(l, [])',
        'l=[[1, 2, 3], [4, 5, 6, 7, 8], [1, 2, 3, 4, 5, 6, 7]] * 10'
    ).timeit()
16.449732065200806

කුඩා ලැයිස්තු සහ කාල නියමය භාවිතා කිරීම: අංකය = 1000000

>>> timeit.Timer(
        '[item for sublist in l for item in sublist]',
        'l=[[1, 2, 3], [4, 5, 6, 7, 8], [1, 2, 3, 4, 5, 6, 7]]'
    ).timeit()
2.4598159790039062
>>> timeit.Timer(
        'reduce(lambda x,y: x+y,l)',
        'l=[[1, 2, 3], [4, 5, 6, 7, 8], [1, 2, 3, 4, 5, 6, 7]]'
    ).timeit()
1.5289170742034912
>>> timeit.Timer(
        'sum(l, [])',
        'l=[[1, 2, 3], [4, 5, 6, 7, 8], [1, 2, 3, 4, 5, 6, 7]]'
    ).timeit()
1.0598428249359131

23
සැබවින්ම කුඩා ලැයිස්තුවක් සඳහා, උදා: උප ලැයිස්තු 3 ක් ඇති, සමහර විට - නමුත් එකතුවෙහි ක්‍රියාකාරීත්වය O (N ** 2) සමඟ යන අතර, ලැයිස්තු අවබෝධය O (N) සමඟ යන බැවින්, ආදාන ලැයිස්තුව ටිකක් වැඩීමෙන් දේවල් ආපසු හැරෙනු ඇත - - ඇත්ත වශයෙන්ම LC වර්ධනය වන විට සීමාවේ එකතුවට වඩා LC “අනන්ත වේගවත්” වනු ඇත. පයිතන් ධාවන වේලාවේදී මුදල සැලසුම් කිරීම සහ එහි පළමු ක්‍රියාවට නැංවීම පිළිබඳ වගකීම මා සතු වූ අතර, එය සාරාංශගත සංඛ්‍යා වලට effectively ලදායී ලෙස සීමා කිරීමට (එය ඇත්තෙන්ම හොඳ දේ) සහ එය මිනිසුන්ට ලබා දෙන “ආකර්ශනීය කරදර” අවහිර කිරීමට ක්‍රමයක් සොයාගත්තේ නම් මම තවමත් ප්‍රාර්ථනා කරමි. ලැයිස්තු "එකතුව" කිරීමට කැමති ;-).
ඇලෙක්ස් මාටෙලි

38

සමඟ ව්යාකූලත්වයක් ඇති බව පෙනේ operator.add! ඔබ ලැයිස්තු දෙකක් එකට එකතු කළ විට, ඒ සඳහා නිවැරදි පදය වන්නේ concatඑකතු කිරීම නොවේ.operator.concatඔබ භාවිතා කළ යුතු දේ.

ඔබ ක්‍රියාකාරී යැයි සිතන්නේ නම්, එය මේ තරම් පහසු ය ::

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

අනුක්‍රමික ගණයට ගරු කිරීම අඩු කරන බව ඔබට පෙනේ, එබැවින් ඔබ ටුපල් එකක් සපයන විට, ඔබ නැවත ටුපල් එකක් ලබා ගනී. ලැයිස්තුවක් සමඟ උත්සාහ කරමු ::

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

ආහා, ඔබ ලැයිස්තුවක් ආපසු ලබා ගන්න.

කාර්ය සාධනය ගැන කෙසේද ::

>>> 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ඉතා වේගවත්! නමුත් එය අඩු කිරීම හා සැසඳීමක් නොවේ concat.

>>> list2d = ((1, 2, 3),(4, 5, 6), (7,), (8, 9))
>>> %timeit reduce(operator.concat, list2d)
1000000 loops, best of 3: 492 ns per loop

1
හ්ම්ම් සාධාරණ දෙවන උදාහරණය ද ලැයිස්තුවක් විය යුතුය (හෝ පළමු
ටුපල්

2
එවැනි කුඩා යෙදවුම් භාවිතා කිරීම සාධාරණ සංසන්දනයක් නොවේ. දිග 1000 අනුපිළිවෙල 1000 සඳහා, මට තත්පර 0.037 ක් list(chain.from_iterable(...))සහ තත්පර 2.5 ක් ලැබේ reduce(concat, ...). ගැටළුව වන්නේ reduce(concat, ...)චතුරස්රාකාර ධාවන කාලය ඇති අතර chainරේඛීය වේ.
kaya3

33

ඔබ දිගුව භාවිතා කරන්නේ ඇයි?

reduce(lambda x, y: x+y, l)

මෙය හොඳින් ක්‍රියාත්මක විය යුතුය.


7
python3 සඳහාfrom functools import reduce
andorov

කණගාටුයි, මන්දගාමී පිළිතුරු බලන්න
Mr_and_Mrs_D

පයිතන් 2 සහ 3 මත ක්‍රියා කරන කෙටි විසඳුම මෙය තේරුම් ගැනීමට පහසුම ක්‍රමයයි. බොහෝ පයිතන් ජනයා දත්ත සැකසීමේදී සිටින බව මට වැටහී ඇති අතර එහිදී දත්ත සැකසීමට විශාල ප්‍රමාණයක් ඇති අතර වේගය ගැන වැඩි සැලකිල්ලක් දක්වයි, නමුත් ඔබ විට ෂෙල් ස්ක්‍රිප්ට් එකක් ලියන අතර උප ලැයිස්තු කිහිපයක ඇත්තේ මූලද්‍රව්‍ය දුසිම් කිහිපයක් පමණි, එවිට මෙය පරිපූර්ණ වේ.
අස්ෆන්ඩ් කාසි

27

more_itertoolsපැකේජය ස්ථාපනය කිරීම සලකා බලන්න .

> pip install more_itertools

එය ක්‍රියාත්මක කිරීම සමඟ නැව්ගත කරයි flatten( ප්‍රභවය , itertools වට්ටෝරු වලින් ):

import more_itertools


lst = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]
list(more_itertools.flatten(lst))
# [1, 2, 3, 4, 5, 6, 7, 8, 9]

2.4 අනුවාදය අනුව, ඔබට වඩාත් සංකීර්ණ, කැදැලි කළ හැකි දෑ සමඟ සමතලා කළ හැකිය more_itertools.collapse( ප්‍රභවය , අබාර්නෙට් විසින් දායක වේ).

lst = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]
list(more_itertools.collapse(lst)) 
# [1, 2, 3, 4, 5, 6, 7, 8, 9]

lst = [[1, 2, 3], [[4, 5, 6]], [[[7]]], 8, 9]              # complex nesting
list(more_itertools.collapse(lst))
# [1, 2, 3, 4, 5, 6, 7, 8, 9]

ඇත්ත වශයෙන්ම. මෙය පිළිගත් පිළිතුර විය යුතුය
brunetton

ඔබේ ව්‍යාපෘතියට පැකේජයක් එක් කිරීම ඔබට දැරිය හැකි නම් - මෙම පිළිතුර වඩාත් සුදුසුය
viddik13

22

ඔබගේ ක්‍රියාකාරීත්වය ක්‍රියාත්මක නොවීමට හේතුව, දිගුව තැනින් තැන අරා විහිදෙන අතර එය නැවත ලබා නොදේ. මේ වගේ දෙයක් භාවිතා කරමින් ඔබට තවමත් ලැම්බඩා වෙතින් x ආපසු ලබා දිය හැකිය:

reduce(lambda x,y: x.extend(y) or x, l)

සටහන: ලැයිස්තු වල + ට වඩා දිගු කිරීම වඩා කාර්යක්ෂම වේ.


7
extendලෙස වඩා හොඳින් භාවිතා newlist = [], extend = newlist.extend, for sublist in l: extend(l)එය ඇති (ඒ වෙනුවට විශාල) පොදු කාර්ය මගහැරෙන ලෙස lambdaමත, විශේෂණය බැලීම x, හා or.
agf

python 3 add සඳහාfrom functools import reduce
Markus Dutschke

17
def flatten(l, a):
    for i in l:
        if isinstance(i, list):
            flatten(i, a)
        else:
            a.append(i)
    return a

print(flatten([[[1, [1,1, [3, [4,5,]]]], 2, 3], [4, 5],6], []))

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

def flatten(l, a=None): if a is None: a = [][...]
පොයික්

16

පුනරාවර්තන අනුවාදය

x = [1,2,[3,4],[5,[6,[7]]],8,9,[10]]

def flatten_list(k):
    result = list()
    for i in k:
        if isinstance(i,list):

            #The isinstance() function checks if the object (first argument) is an 
            #instance or subclass of classinfo class (second argument)

            result.extend(flatten_list(i)) #Recursive call
        else:
            result.append(i)
    return result

flatten_list(x)
#result = [1,2,3,4,5,6,7,8,9,10]

1
හොඳයි, ආනයන අවශ්‍ය නොවන අතර එය කරන්නේ කුමක්ද යන්න පැහැදිලි ය ... ලැයිස්තුවක් සමතලා කිරීම, කාල පරිච්ඡේදය :)
ගෝරන් බී.

1
සරලවම දීප්තිමත්!
සචින් ෂර්මා

15

matplotlib.cbook.flatten() උදාහරණයට වඩා ගැඹුරින් කූඩු කළත් කූඩු ලැයිස්තු සඳහා වැඩ කරනු ඇත.

import matplotlib
l = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]
print(list(matplotlib.cbook.flatten(l)))
l2 = [[1, 2, 3], [4, 5, 6], [7], [8, [9, 10, [11, 12, [13]]]]]
print list(matplotlib.cbook.flatten(l2))

ප්‍රති ult ලය:

[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]

මෙය අවධාරනය කිරීමට වඩා 18x වේගවත් වේ ._. සමතලා කරන්න:

Average time over 1000 trials of matplotlib.cbook.flatten: 2.55e-05 sec
Average time over 1000 trials of underscore._.flatten: 4.63e-04 sec
(time for underscore._)/(time for matplotlib.cbook) = 18.1233394636

14

විචල්‍ය දිග පෙළ පදනම් කරගත් ලැයිස්තු සමඟ කටයුතු කිරීමේදී පිළිගත් පිළිතුර මට වැඩ කළේ නැත. මෙන්න මට වැඩ කළ විකල්ප ප්‍රවේශයකි.

l = ['aaa', 'bb', 'cccccc', ['xx', 'yyyyyyy']]

බව පිළිගත් පිළිතුර නොවේ වැඩ:

flat_list = [item for sublist in l for item in sublist]
print(flat_list)
['a', 'a', 'a', 'b', 'b', 'c', 'c', 'c', 'c', 'c', 'c', 'xx', 'yyyyyyy']

නව යෝජනා විසඳුම කළේ මට වැඩ:

flat_list = []
_ = [flat_list.extend(item) if isinstance(item, list) else flat_list.append(item) for item in l if item]
print(flat_list)
['aaa', 'bb', 'cccccc', 'xx', 'yyyyyyy']

14

ඉහත අනිල්ගේ ක්‍රියාකාරිත්වයේ නරක ලක්ෂණය නම්, පරිශීලකයාට සෑම විටම දෙවන ලැයිස්තුව හිස් ලැයිස්තුවක් ලෙස අතින් නියම කිරීම අවශ්‍ය වේ [] . මෙය පෙරනිමියක් විය යුතුය. පයිතන් වස්තූන් ක්‍රියා කරන ආකාරය නිසා මේවා සැකසිය යුත්තේ ශ්‍රිතය තුළ මිස තර්කවල නොවේ.

මෙන්න වැඩ කරන කාර්යයක්:

def list_flatten(l, a=None):
    #check a
    if a is None:
        #initialize with empty list
        a = []

    for i in l:
        if isinstance(i, list):
            list_flatten(i, a)
        else:
            a.append(i)
    return a

පරීක්ෂා කිරීම:

In [2]: lst = [1, 2, [3], [[4]],[5,[6]]]

In [3]: lst
Out[3]: [1, 2, [3], [[4]], [5, [6]]]

In [11]: list_flatten(lst)
Out[11]: [1, 2, 3, 4, 5, 6]

13

පහත දැක්වෙන්නේ මට සරල බව පෙනේ:

>>> import numpy as np
>>> l = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]
>>> print (np.concatenate(l))
[1 2 3 4 5 6 7 8 9]

විවිධ මානයන් සහිත ලැයිස්තු සඳහා ක්‍රියා නොකරයි. -1
නුරුබ්

10

කෙනෙකුට NumPy හි තට්ටු නිවාසයද භාවිතා කළ හැකිය :

import numpy as np
list(np.array(l).flat)

සංස්කරණය 11/02/2016: ක්‍රියා කරන්නේ උප ලැයිස්තු වලට සමාන මානයන් ඇති විට පමණි.


එය ප්‍රශස්ත විසඳුමක් වේවිද?
RetroCode

6

ඔබට අංක භාවිතා කළ හැකිය:
flat_list = list(np.concatenate(list_of_list))


මෙය සංඛ්‍යාත්මක, නූල් සහ මිශ්‍ර ලැයිස්තු සඳහා ද ක්‍රියා කරයි
නිටින්

2
අසමාන ලෙස කැදැලි දත්ත සඳහා අසමත් වේ, වැනි[1, 2, [3], [[4]], [5, [6]]]
EL_DON

5

ඔබ පිරිසිදු පෙනුම සඳහා වේගය ඉතා කුඩා ප්රමාණයක් අත්හැරීමට කැමති නම්, ඔබ භාවිතා කළ හැකි numpy.concatenate().tolist()හෝ numpy.concatenate().ravel().tolist():

import numpy

l = [[1, 2, 3], [4, 5, 6], [7], [8, 9]] * 99

%timeit numpy.concatenate(l).ravel().tolist()
1000 loops, best of 3: 313 µs per loop

%timeit numpy.concatenate(l).tolist()
1000 loops, best of 3: 312 µs per loop

%timeit [item for sublist in l for item in sublist]
1000 loops, best of 3: 31.5 µs per loop

Doms numpy.concatenate සහ numpy.ravel වෙතින් ඔබට මෙහි වැඩි විස්තර දැනගත හැකිය


1
වැනි අසමාන ලෙස කැදැලි ලැයිස්තු සඳහා ක්‍රියා නොකරයි[1, 2, [3], [[4]], [5, [6]]]
EL_DON

5

මම සොයාගත් වේගවත්ම විසඳුම (කෙසේ වෙතත් විශාල ලැයිස්තුවක් සඳහා):

import numpy as np
#turn list into an array and flatten()
np.array(l).flatten()

කළා! ලැයිස්තුව (l) ක්‍රියාත්මක කිරීමෙන් ඔබට එය නැවත ලැයිස්තුවක් බවට පත් කළ හැකිය


1
මෙය වැරදියි, පැතලි කිරීම මඟින් nd අරාවේ මානයන් එකකට අඩු කරනු ඇත, නමුත් ඇතුළත ලැයිස්තු එකක් ලෙස සංයුක්ත නොවේ.
ඇන්ඩෝ ජුරායි

5

underscore.pyපැකේජ විදුලි පංකාව සඳහා සරල කේතය

from underscore import _
_.flatten([[1, 2, 3], [4, 5, 6], [7], [8, 9]])
# [1, 2, 3, 4, 5, 6, 7, 8, 9]

එය සියලු පැතලි ගැටළු විසඳයි (කිසිවක් ලැයිස්තු අයිතමයක් හෝ සංකීර්ණ කැදැල්ලක්)

from underscore import _
# 1 is none list item
# [2, [3]] is complex nesting
_.flatten([1, [2, [3]], [4, 5, 6], [7], [8, 9]])
# [1, 2, 3, 4, 5, 6, 7, 8, 9]

ඔබට underscore.pyපයිප්පයෙන් ස්ථාපනය කළ හැකිය

pip install underscore.py

ඒ හා සමානව, ඔබට pydash භාවිතා කළ හැකිය . මෙම අනුවාදය ලැයිස්තු අවබෝධය හෝ වෙනත් පිළිතුරු වලට වඩා කියවිය හැකි බව මට පෙනේ.
gliemezis

2
මෙය ඉතා මන්දගාමී ය.
නිකෝ ෂ්ලමර්

2
එයට _ නමින් මොඩියුලයක් ඇත්තේ ඇයි? එය නරක නමක් සේ පෙනේ. Stackoverflow.com/a/5893946/6605826
EL_DON

2
@EL_DON: underscore.py readme පිටුවෙන් "Underscore.py යනු විශිෂ්ට ජාවාස්ක්‍රිප්ට් පුස්තකාලයේ පයිතන් වරායකි underscore.js". මම හිතන්නේ එය මෙම නමට හේතුවයි. ඔව්, එය පයිතන් සඳහා හොඳ නමක් නොවේ
Vu Anh

5
def flatten(alist):
    if alist == []:
        return []
    elif type(alist) is not list:
        return [alist]
    else:
        return flatten(alist[0]) + flatten(alist[1:])

ප්‍රශ්නයේ කැදැලි ලැයිස්තුව සඳහා python2.7 සඳහා අසමත් වේ:[[1, 2, 3], [4, 5, 6], [7], [8, 9]]
EL_DON

@EL_DON පයිතන් මත පරීක්ෂා කර ඇත 2.7.5. එය හොඳින් ක්‍රියාත්මක වේ
ඉංග්‍රීසි කරන්න

5

සටහන : පහත දැක්වෙන්නේ පයිතන් 3.3+ සඳහා එය භාවිතා කරන බැවිනි yield_from. sixඑය ස්ථායී වුවද තෙවන පාර්ශවීය පැකේජයකි. විකල්පයක් ලෙස, ඔබට භාවිතා කළ හැකිය sys.version.


මෙහි දී obj = [[1, 2,], [3, 4], [5, 6]], ලැයිස්තු අවබෝධය සහ itertools.chain.from_iterable. ඇතුළුව සියලු විසඳුම් හොඳයි .

කෙසේ වෙතත්, මෙය තරමක් සංකීර්ණ අවස්ථාව සලකා බලන්න:

>>> obj = [[1, 2, 3], [4, 5], 6, 'abc', [7], [8, [9, 10]]]

මෙහි ගැටළු කිහිපයක් තිබේ:

  • එක් මූලද්‍රව්‍යයක්, 6පරිමාණයක් පමණි; එය නැවත කළ නොහැකි බැවින් ඉහත මාර්ග මෙහි අසාර්ථක වනු ඇත.
  • එක් අංගයක්, 'abc', වේ (සියළුම තාක්ෂණික iterablestr ගේ වේ). කෙසේ වෙතත්, රේඛා අතර තරමක් කියවීම, ඔබට එය එසේ සැලකීමට අවශ්‍ය නැත - ඔබට එය තනි අංගයක් ලෙස සැලකීමට අවශ්‍යය.
  • අවසාන මූලද්‍රව්‍යය, [8, [9, 10]]එයම කැදැලි කළ හැකි ය. මූලික ලැයිස්තු අවබෝධය සහ chain.from_iterable"1 මට්ටම පහළට" පමණක් උපුටා ගන්න.

ඔබට මෙය පහත පරිදි පිළියම් කළ හැකිය:

>>> from collections import Iterable
>>> from six import string_types

>>> def flatten(obj):
...     for i in obj:
...         if isinstance(i, Iterable) and not isinstance(i, string_types):
...             yield from flatten(i)
...         else:
...             yield i


>>> list(flatten(obj))
[1, 2, 3, 4, 5, 6, 'abc', 7, 8, 9, 10]

මෙහිදී, ඔබ පරීක්ෂා කරන්නේ උප මූලද්‍රව්‍යය (1) Iterable, ඒබීසී වෙතින් ලබා ගත හැකි බව itertoolsපමණක් නොව, (2) මූලද්‍රව්‍යය “නූල් වැනි” නොවන බව සහතික කිරීමටද අවශ්‍ය වේ .


1
ඔබ තවමත් පයිතන් 2 ගැළපුම ගැන උනන්දුවක් දක්වන්නේ නම් , yield fromforfor x in flatten(i): yield x
ලූපයකට

5
flat_list = []
for i in list_of_list:
    flat_list+=i

මෙම කේතය ද හොඳින් ක්‍රියාත්මක වන අතර එය ලැයිස්තුව සෑම අතින්ම දිගු කරයි. එය බොහෝ සමාන වුවත් ලූප සඳහා ඇත්තේ එකක් පමණි. එබැවින් එය ලූප සඳහා 2 ක් එකතු කිරීමට වඩා අඩු සංකීර්ණතාවයක් ඇත.


5
from nltk import flatten

l = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]
flatten(l)

මෙහි ඇති අනෙක් බොහෝ අයට වඩා මෙම විසඳුමේ ඇති වාසිය නම් ඔබට පහත ලැයිස්තුවක් තිබේ නම්:

l = [1, [2, 3], [4, 5, 6], [7], [8, 9]]

අනෙක් බොහෝ විසඳුම් දෝෂයක් ඇති අතර මෙම විසඳුම ඒවා හසුරුවයි.


ප්රශ්නයේ "ලැයිස්තු ලැයිස්තුවක්" සඳහන් වේ, නමුත් ඔබේ උදාහරණ ලැයිස්තුවට ලැයිස්තුගත නොවන අයිතමයක් ඇතුළත් වේ. වෙනත් බොහෝ විසඳුම් මුල් ප්‍රශ්නයට ඇලී තිබේ. ඔබේ විසඳුම පුළුල් ගැටළුවක් විසඳයි, නමුත් එයට මූලික නොවන පයිතන් පැකේජයක් (nltk) අවශ්‍ය වන අතර එය පළමුව ස්ථාපනය කළ යුතුය.
simonobo

4

මෙය වඩාත්ම කාර්යක්ෂම ක්‍රමය නොවිය හැකි නමුත් මම සිතුවේ එක් ලයිනර් එකක් (ඇත්ත වශයෙන්ම ලයිනර් දෙකක්) දැමීමටයි. මෙම සංස්කරණ දෙකම අත්තනෝමතික ධූරාවලිය කැදැලි ලැයිස්තු මත ක්‍රියා කරනු ඇති අතර භාෂා ලක්ෂණ (පයිතන් 3.5) සහ පුනරාවර්තනය භාවිතා කරයි.

def make_list_flat (l):
    flist = []
    flist.extend ([l]) if (type (l) is not list) else [flist.extend (make_list_flat (e)) for e in l]
    return flist

a = [[1, 2], [[[[3, 4, 5], 6]]], 7, [8, [9, [10, 11], 12, [13, 14, [15, [[16, 17], 18]]]]]]
flist = make_list_flat(a)
print (flist)

ප්‍රතිදානය වේ

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]

මෙය ගැඹුරින් පළමු ආකාරයෙන් ක්‍රියාත්මක වේ. ලැයිස්තුගත නොවන මූලද්‍රව්‍යයක් සොයා ගන්නා තෙක් පුනරාවර්තනය පහළට ගොස්, පසුව දේශීය විචල්‍යය දිගු කර flistපසුව එය දෙමාපිය වෙත පෙරළේ. flistආපසු ලබා දෙන සෑම විටම , එය flistලැයිස්තු අවබෝධය තුළ මවුපියන් වෙත විහිදේ . එමනිසා, මුලදී, පැතලි ලැයිස්තුවක් ආපසු ලබා දෙනු ලැබේ.

ඉහත සඳහන් එක දේශීය ලැයිස්තු කිහිපයක් නිර්මාණය කර දෙමව්පියන්ගේ ලැයිස්තුව දීර් extend කිරීම සඳහා භාවිතා කරයි. මම හිතන්නේ මේ සඳහා ඇති මාර්ගය flistපහත පරිදි ග්ලෝබල් නිර්මාණය කිරීමක් විය හැකිය .

a = [[1, 2], [[[[3, 4, 5], 6]]], 7, [8, [9, [10, 11], 12, [13, 14, [15, [[16, 17], 18]]]]]]
flist = []
def make_list_flat (l):
    flist.extend ([l]) if (type (l) is not list) else [make_list_flat (e) for e in l]

make_list_flat(a)
print (flist)

ප්‍රතිදානය නැවතත්

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]

කාර්යක්ෂමතාව ගැන මේ අවස්ථාවේ මට විශ්වාස නැත.


උපග්‍රන්ථය (l) වෙනුවට ([l]) දිගු කරන්නේ ඇයි?
මැකීක්

3

පූර්ණ සංඛ්‍යා වල විෂම හා සමජාතීය ලැයිස්තු සඳහා ක්‍රියා කරන තවත් අසාමාන්‍ය ප්‍රවේශයක්:

from typing import List


def flatten(l: list) -> List[int]:
    """Flatten an arbitrary deep nested list of lists of integers.

    Examples:
        >>> flatten([1, 2, [1, [10]]])
        [1, 2, 1, 10]

    Args:
        l: Union[l, Union[int, List[int]]

    Returns:
        Flatted list of integer
    """
    return [int(i.strip('[ ]')) for i in str(l).split(',')]

එය මීට පෙර පළ කර ඇති ᴡʜᴀᴄᴋᴀᴍᴀᴅᴏᴏᴅʟᴇ3000 ට වඩා සංකීර්ණ හා ටිකක් මන්දගාමී ක්‍රමයකි. මම ඊයේ ඔහුගේ යෝජනාව නැවත
සොයාගත්තෙමි

එතරම් නොවේ: wierd_list = [[1, 2, 3], [4, 5, 6], [7], [8, 9], 10]>>nice_list=[1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 0]
tharndt

එක් ලයිනර් ලෙස මගේ කේතය වනුයේ: flat_list = [int(e.replace('[','').replace(']','')) for e in str(deep_list).split(',')]
tharndt

1
ඔබ ඇත්ත වශයෙන්ම හරි +1, ᴡʜᴀᴄᴋᴀᴍᴀᴅᴏᴏᴅʟᴇ3000 යෝජනාව බහු ඉලක්කම් සංඛ්‍යා සමඟ ක්‍රියා නොකරනු ඇත, එය පැහැදිලිව පෙනෙන්නට තිබුණද මම මීට පෙර මෙය අත්හදා බැලුවේ නැත. ඔබේ කේතය සරල කර ලිවිය [int(e.strip('[ ]')) for e in str(deep_list).split(',')]හැකිය. නමුත් සැබෑ භාවිත අවස්ථා සඳහා ඩෙලීට්ගේ යෝජනාවට එකඟව සිටීමට මම යෝජනා කරමි. එය අනවසර ආකාරයේ පරිවර්තනයන් අඩංගු නොවේ, එය වේගවත් හා බහුකාර්ය බැවින් එය ස්වභාවිකවම මිශ්‍ර වර්ග සමඟ ලැයිස්තු හසුරුවයි.
Darkonaut

2
අවාසනාවට නැත. නමුත් මෑතකදී මා මෙහි, මෙම කේතය දුටු: Python පරිචය පොත් 6.1.2
tharndt
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.