Erlang i Ruby mają funkcje spłaszczania tablic. Wydaje się, że jest to takie proste i przydatne narzędzie, które można dodać do języka. Można to zrobić:
>>> mess = [[1, [2]], 3, [[[4, 5]], 6]]
>>> mess.flatten()
[1, 2, 3, 4, 5, 6]
Lub nawet:
>>> import itertools
>>> mess = [[1, [2]], 3, [[[4, 5]], 6]]
>>> list(itertools.flatten(mess))
[1, 2, 3, 4, 5, 6]
Zamiast tego w Pythonie trzeba przebrnąć przez pisanie funkcji spłaszczania tablic od zera. Wydaje mi się to głupie, spłaszczanie tablic jest tak powszechną rzeczą. To tak, jakby napisać niestandardową funkcję do łączenia dwóch tablic.
Googlowałem to bezowocnie, więc pytam tutaj; czy jest jakiś szczególny powód, dla którego dojrzały język, taki jak Python 3, który zawiera sto tysięcy różnych baterii, nie zapewnia prostej metody spłaszczania tablic? Czy pomysł włączenia takiej funkcji został w pewnym momencie omówiony i odrzucony?
python
python-3.x
Hubro
źródło
źródło
extend
ale spłaszczenie byłoby znacznie bardziej eleganckie. Ostrzegam jednak, czy ten wzorzec jest na tyle powszechny, że uzasadnia spłaszczenie w standardowej bibliotece.Odpowiedzi:
Propozycje
flatten
dodania funkcji do standardowej biblioteki pojawiają się od czasu do czasu na listach dyskusyjnych python-dev i python-ideas . Programiści Python zwykle odpowiadają następującymi punktami:Jednopoziomowe spłaszczanie (zamienianie iterowalnego elementu iteracyjnego w pojedynczy iterowalny) jest trywialnym wyrażeniem jednowierszowym
(x for y in z for x in y)
i w każdym razie znajduje się już w standardowej bibliotece pod nazwąitertools.chain.from_iterable
.Jakie są przypadki zastosowania spłaszczania wielopoziomowego ogólnego zastosowania? Czy to naprawdę wystarczające, aby funkcja mogła zostać dodana do standardowej biblioteki?
Jak wielopoziomowe spłaszczanie ogólnego przeznaczenia decyduje, kiedy spłaszczyć, a kiedy zostawić w spokoju? Możesz pomyśleć, że reguła taka jak „spłaszcz wszystko, co obsługuje iterowalny interfejs”, zadziała, ale doprowadziłoby to do nieskończonej pętli
flatten('a')
.Zobacz na przykład Raymond Hettinger :
źródło
flatten
funkcję jednopoziomową można zdefiniować jakolambda z: [x for y in z for x in y]
.flatten
metodę. Implementacja tej metody powinna rekurencyjnie wywoływaćflatten
swój podskładnik, jeśli obiekt jest złożony. Niestety AFAIK nie każda wartość jest obiektem w Pythonie. W Ruby powinno to jednak działać.Jest wyposażony w taką metodę, ale nie nazywa go spłaszczeniem. Nazywa się to „ łańcuchem ”. Zwraca iterator, którego należy użyć za pomocą funkcji list (), aby z powrotem przekształcić go w listę. Jeśli nie chcesz używać *, możesz użyć drugiej wersji „from_iterator”. Działa tak samo w Pythonie 3. Nie powiedzie się, jeśli lista wejściowa nie jest listą.
Kiedyś istniała metoda spłaszczenia w module compiler.ast, ale została ona przestarzała w wersji 2.6, a następnie usunięta w wersji 3.0. Dowolna rekurencja głębokości, niezbędna w przypadku dowolnie zagnieżdżonych list, nie działa dobrze z zachowawczą maksymalną głębokością rekurencji Pythona. Przyczyny usunięcia kompilatora były w dużej mierze spowodowane bałaganem . Kompilator został przekształcony w ast, ale spłaszczenie pozostało w tyle.
Głębokość arbitralną można osiągnąć za pomocą tablic numpy i spłaszczenia biblioteki.
źródło
chain.from_iterator
Funkcja, jak pan powiedział, może być używany tylko do spłaszczyć list dwuwymiarowe. Actualy spłaszczyć funkcja, która przyjmuje żadnych ilości zagnieżdżonych list i zwraca listę jednowymiarowy, nadal będzie masowo przydatna w wielu przypadkach (przynajmniej moim zdaniem)... może dlatego, że sam nie jest tak trudno napisać
... a następnie spłaszcz wszystko, co chcesz :)
źródło