[python] list comprehension: goede praktijk?

Pagina: 1
Acties:

Vraag


  • Salvatron
  • Registratie: April 2003
  • Niet online

Salvatron

Dispereert niet

Topicstarter
Ik gebruik list comprehensions maar dit vind ik er vreemd uitzien omdat regels beginnen en eindigen met "[" en "]" . Is dit een gangbare/normale praktijk?

Dit is een normale list comprehension:

Python:
1
2
3
4
modes=[1,2,3,4,5]
multiplied_numbers=[i*2 for i in modes]
for i in multiplied_numbers:
    print(i)


Hier zie je een list comprehension waarbij de regel code begint met "[" en eindigt met "]":

Python:
1
2
modes=[1,2,3,4,5]
[print(i*2) for i in modes]


Vraag: is dit een acceptabele, normale manier van het gebruik van list comprehensions in python? Ik vind het namelijk vreemd om een regel code met "[" en "]" te beginnen en eindigen.

[ Voor 8% gewijzigd door Salvatron op 14-09-2022 02:00 ]

Lucht en leegte, zegt Prediker, alles is leegte.

Alle reacties


Acties:
  • +1 Henk 'm!

  • DataGhost
  • Registratie: Augustus 2003
  • Laatst online: 01:10

DataGhost

iPL dev

De laatste manier is zeker niet acceptabel. Het werkt wel, maar is erg lelijk. Je maakt eigenlijk een lijst met het resultaat van je print-calls. Die returnen elk None dus je krijgt een lijst [None, None, ...] als resultaat, naast output op je scherm. De eerste manier is prima en daar zijn meerdere variaties op mogelijk. De meest gangbare oplossing daarvoor ligt het dichtst bij je laatste stukje code, maar dan met de loop zelf ongeveer gedaan zoals in je eerste voorbeeld.

  • DaFeliX
  • Registratie: December 2002
  • Laatst online: 02-10 13:41

DaFeliX

Tnet Devver
Ik vermoed dat de auteur van codeblok twee heeft geleerd dat "for" in python vaak onnodig is, en dat er een betere methode is. Alleen vind ik die oplossing echt lelijk.

Ik zou het zelf als volgt doen:

Python:
1
2
3
modes=[1,2,3,4,5]
multiplied_numbers=[i*2 for i in modes]
print(*modes,sep="")


Nog steeds geen "for", maar wel leesbaar

[edit]Of wellicht zo, hoewel iets minder leesbaar als je met ints werkt:

Python:
1
2
3
modes=[1,2,3,4,5]
multiplied_numbers=[i*2 for i in modes]
print(''.join(map(str, modes)))

[ Voor 21% gewijzigd door DaFeliX op 14-09-2022 07:27 ]

Einstein: Mijn vrouw begrijpt me niet


Acties:
  • +1 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Ik zou toch gewoon zoiets doen
Python:
1
2
3
4
5
6
for item in [i*2 for i in modes]:
    print(item)

#of gewoon
for item in modes:
    print(item*2)

List comprehensions zijn erg handig, maar control flow statements zijn ook prima.

In het geval dat je de lijst wel delimeted wil hebben zou ik weer meer de oplossing van @DaFeliX gebruiken
Python:
1
print(', '.join(map(str, [i*2 for i in modes])))

Maar het gebruik van een non-pure function in een list-comprehension zou ik niet doen.

[ Voor 36% gewijzigd door Woy op 14-09-2022 08:21 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • +1 Henk 'm!

  • RayNbow
  • Registratie: Maart 2003
  • Laatst online: 21:41

RayNbow

Kirika <3

Als kanttekening: Python heeft naast list comprehensions ook generator expressions die efficiënter kunnen zijn. Bij een generator expression wordt niet een volledig gevuld lijst-object aangemaakt.

Ipsa Scientia Potestas Est
NNID: ShinNoNoir


  • DataGhost
  • Registratie: Augustus 2003
  • Laatst online: 01:10

DataGhost

iPL dev

Woy schreef op woensdag 14 september 2022 @ 08:18:

In het geval dat je de lijst wel delimeted wil hebben zou ik weer meer de oplossing van @DaFeliX gebruiken
Python:
1
print(', '.join(map(str, [i*2 for i in modes])))

Maar het gebruik van een non-pure function in een list-comprehension zou ik niet doen.
Het gebruik van map wordt doorgaans niet als Pythonic gezien, zeker niet als je het combineert met een list comprehension. Dan is dit gebruikelijker:
Python:
1
2
3
print(', '.join([str(i*2) for i in modes]))
# of impliciet als generator
print(', '.join(str(i*2) for i in modes))

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
DataGhost schreef op woensdag 14 september 2022 @ 09:37:
[...]

Het gebruik van map wordt doorgaans niet als Pythonic gezien, zeker niet als je het combineert met een list comprehension. Dan is dit gebruikelijker:
Python:
1
2
3
print(', '.join([str(i*2) for i in modes]))
# of impliciet als generator
print(', '.join(str(i*2) for i in modes))
Ja helemaal gelijk, ik had vooral gewoon code gekopieerd, maar niet helemaal juist gereplaced ;)

[ Voor 3% gewijzigd door Woy op 14-09-2022 10:33 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • +1 Henk 'm!

  • Ben(V)
  • Registratie: December 2013
  • Laatst online: 20:07
Als het om grote aantallen gaat (dus modes is een lange lijst) dan zou ik een generator gebruiken.
Dat scheelt enorm in geheugen gebruik en snelheid.
Met een list comprehension maakt je een hele nieuwe lijst aan terwijl je alleen het resultaat van elke berekening wilt printen.

Zoiets dus:
code:
1
2
3
4
modes=[1,2,3,4,5]

for Result in (i*2 for i in modes):
    print(Result)

[ Voor 19% gewijzigd door Ben(V) op 15-09-2022 11:40 ]

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


  • DataGhost
  • Registratie: Augustus 2003
  • Laatst online: 01:10

DataGhost

iPL dev

Ben(V) schreef op donderdag 15 september 2022 @ 11:38:
Als het om grote aantallen gaat (dus modes is een lange lijst) dan zou ik een generator gebruiken.
Dat scheelt enorm in geheugen gebruik en snelheid.
Met een list comprehension maakt je een hele nieuwe lijst aan terwijl je alleen het resultaat van elke berekening wilt printen.

Zoiets dus:
code:
1
2
3
4
modes=[1,2,3,4,5]

for Result in (i*2 for i in modes):
    print(Result)
Alleen heb je in dit voorbeeld helemaal geen intermediate lijst of generator nodig, sterker, dat is behoorlijk lelijk. Alleen al tweemaal "for" op dezelfde regel zou een hint moeten zijn. De i*2 doe je dus lekker in de body en dat kan direct bij het printen.

  • Ben(V)
  • Registratie: December 2013
  • Laatst online: 20:07
Uiteraard, maar dit was uiteraard een voorbeeld.
Wat ik wilde zeggen is dat heel vaak een generator een veel betere oplossing is dan een list comprehension.

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!

  • Salvatron
  • Registratie: April 2003
  • Niet online

Salvatron

Dispereert niet

Topicstarter
Ik moet dit allemaal nog even onderzoeken want ik ben niet bekend met o.a. generators.

Lucht en leegte, zegt Prediker, alles is leegte.


Acties:
  • +1 Henk 'm!

  • Ben(V)
  • Registratie: December 2013
  • Laatst online: 20:07

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