funktion: liste tief kopieren (rekursiv)

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Benutzeravatar
PinkPython
User
Beiträge: 4
Registriert: Samstag 17. Januar 2009, 18:40

funktion: liste tief kopieren (rekursiv)

Beitragvon PinkPython » Samstag 17. Januar 2009, 18:55

Hallo,

ich bin Python-Anfänger und wollte daher fragen, ob jemand weiß wie ich am besten eine Liste tief kopieren kann, und wie ich eine möglichst einfache Funktion dazu schreiben kann.

Z.B: Möchte ich:

liste1=[1,2,3,[4,5],6,7]
neueliste= listdeepcopy(liste1)

So, dass auch die verschachtelten listen mitkopiert werden. Die Funktion deepcopy ist daher genau das was das macht, nur ich möchte es nur für listen, und als "eigene" Funktion haben und zwar rekursiv.


Ich habe es so probiert:

Code: Alles auswählen

def listdeepcopy(l):
    k=[]
    for e in l:
        if isinstance( e, list ):
            k.append(listdeepcopy(e))
        else:
            k.append(e)
    return k



Aber mir scheint die Methode trotzdem falsch zu sein :(, da bei k.append(listdeepcopy(e)), man es auch weglassen kann, und somit kein Sinn ergibt. :(
Weiß jemand wie ich das besser machen kann?
Vielen Dank im vorraus.
Benutzeravatar
BlackVivi
User
Beiträge: 762
Registriert: Samstag 9. Dezember 2006, 14:29
Kontaktdaten:

Beitragvon BlackVivi » Samstag 17. Januar 2009, 19:04

Code: Alles auswählen

>>> import copy
>>> copy.deepcopy
<function deepcopy at 0x00AC68B0>
>>> foo = [1,2,3]
>>> bar = foo
>>> foobar = copy.deepcopy(foo)
>>> foo.append(4)
>>> foo, bar, foobar
([1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3])
>>> foobarbar = foo[:]
>>> foo.append(5)
>>> foo, bar, foobar, foobarbar
([1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3], [1, 2, 3, 4])
Benutzeravatar
PinkPython
User
Beiträge: 4
Registriert: Samstag 17. Januar 2009, 18:40

Beitragvon PinkPython » Samstag 17. Januar 2009, 19:07

Danke BlackVivi, aber ich darf hierbei keine python funktione wie copy.deepcopy verwenden, sondern wirklich "eigene" schreiben. Meine Funktion sollte schon ein Methoden-Kopf haben, und eine neue Liste zurückgeben. Ich komme leider bei meiner Funktion nicht sonderlich weiter :(.
Benutzeravatar
DatenMetzgerX
User
Beiträge: 398
Registriert: Freitag 28. April 2006, 06:28
Wohnort: Zürich Seebach (CH)

Beitragvon DatenMetzgerX » Samstag 17. Januar 2009, 19:49

Code: Alles auswählen

#!/usr/bin/env python
#-*- coding: utf-8 -*-

def copy(iter):
    result = list()
    for item in iter:
        if isinstance(item, list):
            result.append(copy(item))
        else:
            result.append(item)
           
    return result


if __name__ == '__main__':
    l = ["abe", 2, 3, 4, 5, [23, 45]]
    c = copy(l)
   
    l.append(10)
    c.append(34)
    c[0] = c[0] + "t"
    c[5].append(90)
   
    print l
    print c


Funktioniert bei mir bestens, Python 2.5.2
Benutzeravatar
PinkPython
User
Beiträge: 4
Registriert: Samstag 17. Januar 2009, 18:40

Beitragvon PinkPython » Samstag 17. Januar 2009, 22:21

stimmt, ich war nur etwas irritiert, wegen der Zeile 8. Wenn man da im append, den rekursiven Aufruf weglässt, ändert sich nichts.
Danke!

Noch eine kleine Frage, kann ich statt ininstanceof, auch:

Code: Alles auswählen

if type(e)==list:


schreiben? Im Prinzip hätte es den selben Effekt, aber ist es besser type oder isinstanceof zu verwenden?
Birne94
User
Beiträge: 90
Registriert: Freitag 28. November 2008, 15:18
Kontaktdaten:

Beitragvon Birne94 » Samstag 17. Januar 2009, 22:49

es ist besser, weil man dann imo auch abgeleitete Klassen erfasst, odder??
Benutzeravatar
cofi
Moderator
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Beitragvon cofi » Samstag 17. Januar 2009, 22:56

Code: Alles auswählen

In [1]: class AnotherList(list):
   ...:     pass
   ...:

In [2]: alist = AnotherList()

In [3]: isinstance(alist, list)
Out[3]: True


Man sollte aber vielleicht jedes iterable - ausser Strings - einschliessen, um wirklich ein deepcopy zu schaffen ... aber existiert ja schon ;)
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Beitragvon HWK » Sonntag 18. Januar 2009, 10:44

PinkPython hat geschrieben:Danke BlackVivi, aber ich darf hierbei keine python funktione wie copy.deepcopy verwenden, sondern wirklich "eigene" schreiben. Meine Funktion sollte schon ein Methoden-Kopf haben, und eine neue Liste zurückgeben. Ich komme leider bei meiner Funktion nicht sonderlich weiter :(.
Du kannst Dir aber ja trotzdem mal die Implementierung der Methode deepcopy in Python26/Lib/copy.py anschauen.
MfG
HWK
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Beitragvon Darii » Sonntag 18. Januar 2009, 11:03

PinkPython hat geschrieben:stimmt, ich war nur etwas irritiert, wegen der Zeile 8. Wenn man da im append, den rekursiven Aufruf weglässt, ändert sich nichts.
Danke!
Nein kann man nicht. Probier mal

Code: Alles auswählen

liste1 = [1,2,3,[4,5],6,7]
liste2 = liste1[3]
liste3 = listdeepcopy(liste1)
liste2[1] = 23
print liste3

mit und ohne rekursiven Aufruf.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Beitragvon numerix » Sonntag 18. Januar 2009, 13:10

PinkPython hat geschrieben:Noch eine kleine Frage, kann ich statt ininstanceof, auch:

Code: Alles auswählen

if type(e)==list:

schreiben? Im Prinzip hätte es den selben Effekt, aber ist es besser type oder isinstanceof zu verwenden?


Die library reference sagt (http://docs.python.org/library/functions.html)
type(object)¶
Return the type of an object. The return value is a type object. The isinstance() built-in function is recommended for testing the type of an object.
Benutzeravatar
PinkPython
User
Beiträge: 4
Registriert: Samstag 17. Januar 2009, 18:40

Beitragvon PinkPython » Sonntag 18. Januar 2009, 14:02

Dankeschööööön, jetzt habe ich es verstanden. Das Forum ist einfach super ;-). Danke an alle.

Wer ist online?

Mitglieder in diesem Forum: Bing [Bot]