Välkommen till linuxportalen.se!

Linuxportalen.se är Sveriges största och aktivaste webbplats för användare av öppen- och fri programvara.

Du besöker Linuxportalen.se som gäst vilket begränsar din möjlighet att använda webbplatsens alla funktioner. Genom att registera dig som medlem får du inte bara möjlighet att söka bland webbplatsens innehåll, skapa nya och delta i befintliga diskussioner, skapa din egen blogg, kommunicera med andra medlemmar genom privata meddelanden och delta i omröstningar. Du får också tillgång till Veckans Kadavro - en seriestrip unikt skapad för Linuxportalen.se!

Registeringen sker snabbt och är helt kostnadsfri - tveka inte, bli medlem idag!

python, ternary ifs och lambda

PHP har länge haft sin ternary-if som språket lånat från C (om jag inte minns fel) och som C snott från Algol (återigen hoppas jag att minnet inte sviker mig).
Pythons har länge saknat den konstruktionen och man har fått använda sig av def eller lambda. Nu finns den men ser lite annorlunda ut:
 
print "mindre eller lika" if 1<=2 else "större"
 
Jag tycker att det ser snyggare ut än:
print (1<=2)?"mindre eller lika":"större"
 
Ternary ifs används istället för att skriva:

if 1<=2:
  print "mindre eller lika"
else:
  print "större"

 
Ett rätt konkret exempel är att skriva ut data till en webbsida och se till att varannan rad är vit och varannan grå.
 

lista = 'ett två tre fyra fem'.split()
a = 1
for i in lista:
  col = '#CCCCCC' if a%2 else '#FFFFFF'
  a += 1
  print '<tr bgcolor=%s><td>%s</td></tr>' % (i, col)

 
Ett annat sätt att lösa det här (i detta specifika fall) kunde ha varit:

lista = 'ett två tre fyra fem'.split()
a = 1
for i in lista:
  col=['#CCCCCC','#FFFFFF']
  a += 1
  print '<tr bgcolor=%s><td>%s</td></tr>' % (i, col[a%2])

Men är lambda död (som vissa anser) bara för att python fått en ternary-option?
De som säger det måste ha ett smärre problem på loftet med tomtar som ränner runt i lite oönskad omfattning. Så länge map och filter tillsammans med lambda är det bästa sättet att attackera listor och dictionarys.
Eller vilken lösning föredras för att radera ut udda siffror ur en lista:
 

a=range(1,21)
print filter(lambda x: not x%2, a)

eller

a=range(1,21)
for i in a:
  if i%2: a.remove(i)
print a

Alternativ för kommentarvisning

Välj ditt önskade sätt att visa kommentarerna och klicka på "Spara" för att verkställa dina ändringar.

smygiss bild

Ang:

a=range(1,21)
print filter(lambda x: not x%2, a)

och

a=range(1,21)
for i in a:
  if i%2: a.remove(i)
print a

är nr 1 helt klart att föredra. Varför?
Jo.

>>> a = [1,2,3,3,4,5,6,7]
>>> for i in a:
...   if i%2: a.remove(i)
... 
>>> print a
[2, 3, 4, 6]

Och det ser vi ju är helt galet. Felet du gör är att du modifierar variablen du itererar över.
om vi har listan [1,2,3,3,4] och kör den genom den loopen kommer den först ta bort 1, då 1 % 2 = 1. Och då blir a.next() inte 2 utan 3. För två blir ju första elementet. Och 3 % 2 = 1 så trean tas bort och a.next() blir 4. Den missar en trea.
Om man ska göra så så ska man göra en kopia av listan.

Det rekomenderade pythonsättet att göra detta är

>>> print [i for i in range(1,21) if not i%2]
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

Och där ser du en list comprehension. Vilket är något av det bästa i python.

marwals bild

Även om du först introducerar helt nya förutsättningar och sedan kallar det jag gör helt galet, är jag glad att någon mer gillar python och vill skriva om det Smile
---

smygiss bild

Oj då, det kanske blev lite fel där.

Det var resultatet vid de 'helt nya förutsättningar'na jag kallde helt galet. Inte det du gjorde. Om man är helt 100% säker på vad som kommer in i den loopen så är det ingen fel på den. Men hur ofta kan man vara helt säker på det? Den är lite av en osäkrad pistol med småtrasig avtryckare. Det fungerar kanske men den kan bränna av av sig själv då man har den i fickan.

>>> a=range(1,21)
>>> for i in a[:]:
...   if i%2: a.remove(i)
... 
>>> print a
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
>>>
>>> a = [1,2,3,3,4,5,6,7]
>>> for i in a[:]:
...   if i%2: a.remove(i)
... 
>>> print a
[2, 4, 6]

marwals bild

Absolut, jag är med dig. Jag är också uppfostrad i att aldrig lita på indata. Men i exempel tar jag mig vissa friheter Wink
---

smygiss bild

Känner man för att skriva lite extra kod på den första så kan man köra som såhär:

>>> def colour(i=0):
...     while True:
...             yield ('#CCCCCC', '#FFFFFF')[i%2]
...             i += 1                           
... 
>>> color = colour()
>>> lista = 'ett tva tre fyra fem'.split()
>>> for i in zip(color, lista):
...     print '\n\t%s\n' % i
... 

        ett


        tva


        tre


        fyra


        fem


marwals bild

snyggt! Det där antecknas genast.
---

smygiss bild

Hmm det vart lite mystiskt.

Den hackade bort alla [pilåtvänster]tr> för mig Sad
http://pastebin.se/106350 Så ska det se ut, Och mina åäö gick sönder nu också. Vad händer!

hoths bild

Använder du hakar på det sättet så tolkas de som HTML-taggar och eftersom du bara har en hake så är den trasig. Se länk nedan för korrekt kodning av specialtecken.
http://www.linuxportalen.se/filter/tips

 
----
Kom ihåg; 2007 blir det år då Linux slår igenom på allvar.

----
Linux växer snabbast!