zamiana sekwencji zagnieżdżonej na jednowymiarowa postać

zamiana sekwencji zagnieżdżonej na jednowymiarowa postać
PR
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 13
0

Witam. Mam napisać rekurencyjna funkcje generatora która będzie przekształcać zagnieżdżone sekwencję do postaci jednowymiarowej w postaci listy wartości np.
([1,'pies'],3,(4,5[6,7,8])) ->[1,'pies',3,4,5,6,7,8]
Nie wiem jak przemienić poniższy kod na funkcje generatora
Każda pomoc się przyda, z góry dziękuję.

Kopiuj
def przeksztalc(zagn, elist):
    if isinstance(zagn, (list, tuple)):
        if zagn:
            przeksztalc(zagn[0], elist)
            przeksztalc(zagn[1:], elist)
    else:
        elist.append(zagn)
lista = ([1,'abcd'],('kot', 3), ([4, (5, 6, 7)], 8, [9]))
lista2 = []
przeksztalc(lista, lista2)
print(lista2)
AN
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 989
0

Aby stworzyć generator musisz skorzystać z yield. Czyli zamiast dodawać do listy musisz zacząć "zwracać" to yieldem

M9
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 42
0

Coś w tym stylu:

Kopiuj
def flat(arr):
   if (arr nie jest tupla ani lista)
      return [arr]
   if (arr jest tupla lista z jednym elementem)
      return arr

    return flat(arr[0]) + flat(arr[1:])

Pisałem na żywca nie dam sobie ręki uciąć, że jest dobrze

AN
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 989
0

Bo printujesz pewnie pustą listę zamiast to co zwraca generator. Pokaż kod, w którym użyłeś yieldów to doradzimy

M9
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 42
0

W nawiązaniu do komentarza do mojego posta wyżej

Kopiuj
def flat(arr):
    for e in arr:
        if e jest tuplem lub arrayem:
            yield from flat(e)
        else:
            yield e
PR
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 13
0
Kopiuj
def przeksztalc(zagn):
    for e in zagn:
        if isinstance(e, (tuple, list)):
            yield from przeksztalc(e)
    else:
        yield e


lista = ([1, 'abcd'], ('kot', 3), ([4, (5, 6, 7)], 8, [9]))
przeksztalc(lista)

print(lista)

gdzieś coś zepsułem i nie bardzo działa tak jak powinno

lion137
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 5025
0

A da się w ogóle zrobić rekurencyjne z yield?

M9
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 42
1

Tutaj jeszcze w pełni rekurencyjnie:

Kopiuj
def flat(arr):
   if not isinstance(arr, (tuple, list)):
    yield arr
   elif len(arr) > 0:
   	yield from flat(arr[0])
   	yield from flat(arr[1:])
Spearhead
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1007
0

Można to uogólnić sprawdzając czy typ jest iterowalny, a nie tylko czy jest listą bądź krotką (tylko trzeba osobno obsłużyć napisy i bajty).

Kopiuj
from collections.abc import Iterable

def flatten(items, ignore_types=(str, bytes)):
	for x in items:
		if isinstance(x, Iterable) and not isinstance(x, ignore_types):
			yield from flatten(x)
		else:
			yield x
PR
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 13
0

jest taka lista lista = ([1, 'kot', 'mama'], 3, (4, 5, [7, 8, 9]))
i ciekaw jestem czemu po wywołaniu

Kopiuj
yield from przeksztalc(zagn[0])
        yield from przeksztalc(zagn[2])

wynikiem jest [1, 'mama', 4, 7, 9] a po wywołaniu samego yield from przeksztalc(zagn[2]) wynikiem jest ostatnia cyfra czyli 9

M9
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 42
1
Kopiuj
zagn = ([1, 'kot', 'mama'], 3, (4, 5, [7, 8, 9]))

yield from przeksztalc(zagn[0]) //[1, 'kot', 'mama']
    yield from przeksztalc(zagn[0]) // 1  <--
    yield from przeksztalc(zagn[2]) // 'mama' <--
yield from przeksztalc(zagn[2])  // [4,5,[7,8,9]]
    yield from przeksztalc(zagn[0]) //  4 <--
    yield from przeksztalc(zagn[2]) // [7,8,9]
           yield from przeksztalc(zagn[0]) // 7 <--
           yield from przeksztalc(zagn[2]) // 9 <--

Tak to wygląda rekurencyjnie dla pierwszego przypadku po //podałem wartość wyciąganej zagn. I <-- zaznaczyłem to co trafi do ostatecznego wyniku. Zrób sobie tak dla drugiego przypadku

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.