[python] list.append voegt variable toe ipv waarde ?

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • heuveltje
  • Registratie: Februari 2000
  • Laatst online: 13-09 17:56

heuveltje

KoelkastFilosoof

Topicstarter
Ik probeer van een array elke regel op te splitten in diverse gedeeltes, en deze in een nieuw array te zetten
(mensen van Advent of Code 2020 zullen dit vast wel herkennen :) )

Daarvoor heb ik een volgend stukje code geschreven:
Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
zak_kleuren = []
huidige_regeldochterkleuren = []

for huidige_regel in AR_kleurenlijst :
    substring = huidige_regel.split(' contain ')
    huidige_regel_Moederkleur = substring[0][:-5]
    Dochter_substrings = substring[1].split(', ')
   
    huidige_regeldochterkleuren.clear()
    for ii in Dochter_substrings :
        huidige_regeldochterkleuren.append(ii)
    
    zak_kleuren.append([huidige_regel_Moederkleur,huidige_regeldochterkleuren])
        
print(zak_kleuren)


in mijn ogen doet ik dit :
ik split een string op in een lijst van strings ( for ii in Dochter_substrings : huidige_regeldochterkleuren.append(ii) )
en ik voeg die lijst toe aan als een nieuwe regel aan een lijst (ak_kleuren.append([huidige_regel_Moederkleur,huidige_regeldochterkleuren])

Echter In plaats van de waarde van huidige_regeldochterkleuren toe te voegen. voeg ik blijkbaar de variable zelf toe. Want op het moment dat ik die variable clear. clear ik ook alle waardes in zak_kleuren

Wat niet is wat ik verwachte dat er zou gebeuren,
Daarom dat ik een simpele test geschreven heb, om te checken dat ik niet gek was :
Python:
1
2
3
4
5
6
7
8
9
10
11
test_list = []

lijst = ['a','b','c']
char = '1'
test_list.append([char,lijst])

lijst = ['Dit','is','een lijst']
char = '2'
test_list.append([char,lijst])

print(test_list)

Levert [['1', ['a', 'b', 'c']], ['2', ['Dit', 'is', 'een lijst']]] op als resultaat.

Dus de waarde van de variable op het moment dat ik append aanroep is wat er in gezet is. en als ik achteraf de waarde van de variable verander blijft die in de array onverandered. Dat is ook zoals ik verwacht dat het werkte. Echter ik zie niet wat ik in het 2e code anders doe dan de eerste keer :?

waarom voeg ik 1 keer de variable toe, en de 2e keer de waarde van die variable ?

Heuveltjes CPU geschiedenis door de jaren heen : AMD 486dx4 100, Cyrix PR166+, Intel P233MMX, Intel Celeron 366Mhz, AMD K6-450, AMD duron 600, AMD Thunderbird 1200mhz, AMD Athlon 64 x2 5600, AMD Phenom X3 720, Intel i5 4460, AMD Ryzen 5 3600 5800x3d

Alle reacties


Acties:
  • +1 Henk 'm!

  • CyBeR
  • Registratie: September 2001
  • Niet online

CyBeR

💩

Het verschil is dat je de originele array clear()t. Doe dit en 't zou moeten werken:

Python:
1
zak_kleuren.append([huidige_regel_Moederkleur,huidige_regeldochterkleuren.copy()])


(Uitgaande van Python 3).

[ Voor 7% gewijzigd door CyBeR op 07-12-2020 22:07 ]

All my posts are provided as-is. They come with NO WARRANTY at all.


Acties:
  • 0 Henk 'm!

  • heuveltje
  • Registratie: Februari 2000
  • Laatst online: 13-09 17:56

heuveltje

KoelkastFilosoof

Topicstarter
Je oplossing doet het in ieder geval. dus dat is alvast iets :)
Echter ik begrijp helaas nog steeds waarom ik een copy moet doen.
in mijn beleving is dat het default gedrag bij elke append.

Even test 2 iets aangepast.
Python:
1
2
3
4
5
6
7
8
9
10
11
test_list = []

char = '1'
lijst = ['a','b','c']
test_list.append([char,lijst])

char = '2'
lijst.clear()
test_list.append([char,lijst])

print(test_list)

geeft als output : [['1', ['a', 'b', 'c']], ['2', []]]

Nu doe ik hetzelfde (toch:?) ik heb een variable lijst, die append ik aan een test_list.
En als ik met lijst.clear die lijst wis. verandert de eerder toegevoegde waarde in test_list niet


Ok ik word langzaam gek denk ik, nu geeft het inderdaad wel [['1', []], ['2', []]] als output.
Maar ik heb niks veranderd bij mijn weten, en het eerdere antwoord is echt gepaste uit de VS console. :?

te veel weirdheid voor 1 avond, morgen maar eens met een fris hoofd naar kijken.

[ Voor 19% gewijzigd door heuveltje op 07-12-2020 22:39 ]

Heuveltjes CPU geschiedenis door de jaren heen : AMD 486dx4 100, Cyrix PR166+, Intel P233MMX, Intel Celeron 366Mhz, AMD K6-450, AMD duron 600, AMD Thunderbird 1200mhz, AMD Athlon 64 x2 5600, AMD Phenom X3 720, Intel i5 4460, AMD Ryzen 5 3600 5800x3d


Acties:
  • 0 Henk 'm!

  • CyBeR
  • Registratie: September 2001
  • Niet online

CyBeR

💩

Bij mij komt daar wat je verwacht uit, gegeven je originele vraag:

[marco@lavinia tmp]$ cat test.py 
test_list = []

char = '1'
lijst = ['a','b','c']
test_list.append([char,lijst])

char = '2'
lijst.clear()
test_list.append([char,lijst])

print(test_list)
[marco@lavinia tmp]$ python3 test.py 
[['1', []], ['2', []]]


Het verhaal is vrij simpel namelijk dat er een reference naar je list wordt opgenomen, niet een kopie van de list. Dat los je op met copy() (of op een aantal andere manieren waarmee je hetzelfde bereikt.)

[ Voor 78% gewijzigd door CyBeR op 07-12-2020 22:40 ]

All my posts are provided as-is. They come with NO WARRANTY at all.


Acties:
  • 0 Henk 'm!

  • Raynman
  • Registratie: Augustus 2004
  • Laatst online: 20:10
heuveltje schreef op maandag 7 december 2020 @ 22:25:
Echter ik begrijp helaas nog steeds waarom ik een copy moet doen.
Maar zelf had je eigenlijk ook een copy geïmplementeerd in regel 9 t/m 11 van je oorspronkelijke code.

Het is sowieso goed om te begrijpen wat er gebeurt -- elke basiscursus zou moeten uitleggen hoe variabelen naar objecten verwijzen in het geheugen -- maar als je die handmatige copy en vooral het hergebruik van huidige_regeldochterkleuren achterwege laat, heb je het hele probleem niet:
Python:
1
2
3
4
5
6
7
8
9
zak_kleuren = []

for huidige_regel in AR_kleurenlijst :
    substring = huidige_regel.split(' contain ')
    huidige_regel_Moederkleur = substring[0][:-5]
    Dochter_substrings = substring[1].split(', ')
    zak_kleuren.append([huidige_regel_Moederkleur, Dochter_substrings])
        
print(zak_kleuren)

Acties:
  • 0 Henk 'm!

  • hostname
  • Registratie: April 2009
  • Laatst online: 19:56
heuveltje schreef op maandag 7 december 2020 @ 22:01:
Ik probeer van een array elke regel op te splitten in diverse gedeeltes, en deze in een nieuw array te zetten
waarom voeg ik 1 keer de variable toe, en de 2e keer de waarde van die variable ?
Python voegt altijd de waarde van de variable toe. In het geval van huidige_regel_Moederkleur is dat een string, en gedraagt het zich dus zoals jij verwacht. In het geval van huidige_regeldochterkleuren is de waarde een lijst, en wordt dus ook die lijst toegevoegd. Dat is wat anders dan de waarden die in de lijst zitten, zoals je lijkt te verwachten. De variable zelf wordt niet toegevoegd. Als je in plaats van clear() een nieuwe lijst aan huidige_regeldochterkleuren toewijst (door middel van huidige_regeldochterkleuren = []), dan verwijst de variable nu naar een andere lijst dan degene die je hebt toevoegd aan zak_kleuren, en zal het wel werken zoals je had gehoopt.

[ Voor 5% gewijzigd door hostname op 07-12-2020 22:54 ]

Pagina: 1