2 manieren om een list te maken in Python waarom verschil

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • henk.bokhove
  • Registratie: Februari 2020
  • Laatst online: 04-04-2024
Mijn vraag
Onderstaande uitgeprinte list's lijken het zelfde maar de uitkomsten zijn verschillend, ik begrijp niet waarom.

Relevante software en hardware die ik gebruik
Python:
1
2
3
4
5
6
7
8
9
.#eerste manier
letterlijst=[[0]*3]*26
letterlijst[2][1]=1
print(letterlijst)
#tweede manier
print("-------------------------------------------------------------")
letterlijst = [ 3*[0] for i in range( 26 ) ]
letterlijst[2][1]=1
print(letterlijst)..


Wat ik al gevonden of geprobeerd heb
...

[ Voor 2% gewijzigd door RobIII op 25-02-2020 16:36 . Reden: Code tags toegevoegd. ]

Alle reacties


Acties:
  • +2 Henk 'm!

  • Wintervacht
  • Registratie: December 2016
  • Laatst online: 07-08 10:04

Wintervacht

☉ ‿ ⚆

henk.bokhove schreef op dinsdag 25 februari 2020 @ 16:16:
Wat ik al gevonden of geprobeerd heb
...
Misschien moet je hier maar mee beginnen dan :p

Weet een beetje van veel dingen en veel van een paar dingen.


Acties:
  • 0 Henk 'm!

  • armageddon_2k1
  • Registratie: September 2001
  • Laatst online: 27-07 10:18
Invullen in de REPL geeft dit:
code:
1
2
>>> [3*[0] for _ in range(26)] == [[0]*3]*26
True


Dus... tja, geen verschil. Het gaat ergens anders fout denk ik

Engineering is like Tetris. Succes disappears and errors accumulate.


Acties:
  • +1 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 27-09 13:03
Toch is het niet hetzelfde. Kijk hier even naar het nested lists gedeelte: https://snakify.org/en/lessons/two_dimensional_lists_arrays

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • +1 Henk 'm!

  • MaNDaRK
  • Registratie: Oktober 2001
  • Laatst online: 09:21
De uitkomst is inderdaad verschillend (wat ik niet had verwacht), mogelijk komt dit doordat je bij de eerste lijst 26x de volgende lijst:
[0, 0, 0]
kopieert.

En bij de tweede lijst is het geen kopie, maar je gegenereerd wel een onafhankelijke lijst.

Python:
1
2
3
4
5
6
7
8
9
10
11
letterlijst1 = [[0]*3]*26
# letterlijst1[2][1] = 0
print(letterlijst1)
# tweede manier
print("-"*40)
letterlijst2 = [3*[0] for _ in range(26)]
# letterlijst2[2][1] = 1
print(letterlijst2)

if letterlijst1 == letterlijst2:
    print("wij zijn gelijk!")


Geeft als uitkomst:
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0],
 [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
----------------------------------------
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0],
 [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
wij zijn gelijk!

Acties:
  • +1 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 27-09 13:03
MaNDaRK schreef op dinsdag 25 februari 2020 @ 17:18:
De uitkomst is inderdaad verschillend (wat ik niet had verwacht), mogelijk komt dit doordat je bij de eerste lijst 26x de volgende lijst:
[0, 0, 0]
kopieert.
In het eerste geval maak je een lijst met 3 items, waarna je een lijst met daarin 26x een reference naar eerste lijst maakt. Maw, als je vervolgens de lijst op index 0 aanpast, zijn ze allemaal aangepast, ze refereren immers aan dezelfde lijst:

Python:
1
2
3
4
5
6
 l = [[0]*3]*26
 l
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
 l[0][0]=1
 l
[[1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0]]

[ Voor 37% gewijzigd door farlane op 25-02-2020 23:24 ]

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • henk.bokhove
  • Registratie: Februari 2020
  • Laatst online: 04-04-2024
MaNDaRK vergelijkt de de 2 lists en Python trekt de conclusie dat ze gelijk zijn maar in gebruik blijkbaar niet.
Echt helemaal duidelijk is het voor mij nog niet.

Acties:
  • +3 Henk 'm!

  • ThomasG
  • Registratie: Juni 2006
  • Laatst online: 23-09 14:00
Python:
1
lijst=[[0]*3]*4
Is hetzelfde als wanneer je het volgende zou doen:
Python:
1
2
a=[0, 0, 0]
lijst=[a, a, a, a]


Python:
1
lijst=[3*[0] for i in range(4)]
Is hetzelfde als wanneer je het volgende zou doen:
Python:
1
2
3
4
5
a=[0, 0, 0]
b=[0, 0, 0]
c=[0, 0, 0]
d=[0, 0, 0]
lijst=[a, b, c, d]

Acties:
  • +1 Henk 'm!

  • Ben(V)
  • Registratie: December 2013
  • Nu online
henk.bokhove schreef op woensdag 26 februari 2020 @ 16:04:
MaNDaRK vergelijkt de de 2 lists en Python trekt de conclusie dat ze gelijk zijn maar in gebruik blijkbaar niet.
Echt helemaal duidelijk is het voor mij nog niet.
De eerste is een lijst van 26 elementen van ieder 3 diep.
Een tweedimensionale lijst van 26 * 3 dus.

Als je zoals bij het tweede voorbeeld met behulp van een list comprehension een lijst maak dan hebt je enkel drie elementen en 26 * 3 verwijzingen (pointers) naar die drie elementen.
Als je er dan een wijzigt lijkt het alsof je ze alle 26 wijzigt, maar het zijn enkel pointers, dus blijven ze allemaal naar die drie elementen wijzen.

All truth passes through three stages: First it is ridiculed, second it is violently opposed and third it is accepted as being self-evident.


  • henk.bokhove
  • Registratie: Februari 2020
  • Laatst online: 04-04-2024
De benaderingen van ThomasG en Ben(V) lijken mij juist dus blijkbaar voegt de tweede manier toch iets toe wat in de eerste methode niet gebeurt, mijn dank.

  • Ben(V)
  • Registratie: December 2013
  • Nu online
Ach het is maar wat je een toevoeging vind.
Wat zou het nut zijn van 26 verwijzingen naar 3 variabelen?

Meestal heb je gewoon een echte lijst nodig zoals op de eerste manier het geval is.

All truth passes through three stages: First it is ridiculed, second it is violently opposed and third it is accepted as being self-evident.


Acties:
  • +2 Henk 'm!

  • Morrar
  • Registratie: Juni 2002
  • Laatst online: 12:20
Wellicht handig in dit kader: de id() functie in Python geeft het object / referentie ID terug, zodat je kunt zien welke variabelen naar hetzelfde object wijzen.

Bijvoorbeeld voor letterlijst:

Python:
1
2
3
4
5
6
7
letterlijst = [[0] * 3] * 26
print([id(x) for x in letterlijst])
# print 26x hetzelfde ID

letterlijst = [3 * [0] for _ in range(26)]
print([id(x) for x in letterlijst])
# print 26 verschillende IDs


Ook wel goed om te lezen:
https://towardsdatascienc...able-objects-829a0cb1530a
https://medium.com/@megha...de-of-python-c2145cf72747

[ Voor 42% gewijzigd door Morrar op 28-02-2020 14:24 ]


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 27-09 13:03
Ben(V) schreef op woensdag 26 februari 2020 @ 17:12:
[...]
De eerste is een lijst van 26 elementen van ieder 3 diep.
Een tweedimensionale lijst van 26 * 3 dus.

Als je zoals bij het tweede voorbeeld met behulp van een list comprehension een lijst maak dan hebt je enkel drie elementen en 26 * 3 verwijzingen (pointers) naar die drie elementen.
Als je er dan een wijzigt lijkt het alsof je ze alle 26 wijzigt, maar het zijn enkel pointers, dus blijven ze allemaal naar die drie elementen wijzen.
-O-
Maar dan precies andersom ....

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • Ben(V)
  • Registratie: December 2013
  • Nu online
Wat bedoel je?

All truth passes through three stages: First it is ridiculed, second it is violently opposed and third it is accepted as being self-evident.


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 27-09 13:03
Dat je de 2 versies precies verkeerd om hebt. Bovendien heb je niet 26*3 verwijzingen maar 26 verwijzingen naar een lijst met 3 elementen.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • Ben(V)
  • Registratie: December 2013
  • Nu online
Je hebt gelijk het is precies andersom.

All truth passes through three stages: First it is ridiculed, second it is violently opposed and third it is accepted as being self-evident.

Pagina: 1