Programming4Fun

Programming4Fun - programujemy z pasją :)

  • Nie jesteś zalogowany.

Ogłoszenie


#1 2014-07-10 22:29:38

 Hoguzzos

http://winclub.pl/public/style_extra/team_icons/mod.png

Skąd: Za górami za lasami :D
Zarejestrowany: 2014-07-09
Posty: 56
Punktów :   

Kurs Pythona. Część 11.

ŹRÓDŁO : http://szgrabowski.kis.p.lodz.pl/Python-podstawy.html
Pożyteczne narzędzia: split, join, sum, map, filter, reduce.
Nie omówiliśmy jeszcze dwóch niezwykle przydatnych metod działających dla obiektów typu string.  Metoda split() tworzy listę słów danego napisu, metoda join() tworzy string łącząc stringi na liście przekazanej jako argument.



Przykłady:

Kod:

s = "Pies, lis i 2 koty"

lista = s.split()

print lista

s1 = "*".join(lista)

print s1

Wypróbuj join na rzecz stringu "***".  Albo na rzecz stringu pustego.



Wnikliwy obserwator dostrzeże, że tokenizacja nie jest może doskonała: pierwsze słowo listy w naszym przykładzie kończy się przecinkiem, co może być niepożądane przy tworzeniu rozmaitych słowników, list użytkowników etc.  Brak argumentu przy split() oznacza (dowolnej długości) ciąg białych znaków, ale gdybyśmy mieli inne separatory, np. dla:

Kod:

s = "Pies,lis,kot"

to wystarczyłoby utworzyć listę słów w taki sposób:

Kod:

lista = s.split(",")

Niestety, nasz przypadek jest jeszcze inny (separatorem jest albo spacja, albo np. przecinek+spacja) i rozwiązanie „problemu” odłożymy na później, gdy będziemy znali wyrażenia regularne, gdyż one są tu najprostszą drogą do osiągnięcia celu.



Oto jeszcze parę przykładów użycia split lub join:

Kod:

 

email = "Lord.Vader@dark.side.pl"

lista = email.split("@")

page_footer = "Pisz do mnie pod: " + lista[0] + " (małpa) " + lista[1]

print page_footer

A może ambitniej chcemy się chronić przed spamem?  Proponuję taki kodzik (po dwóch pierwszych liniach powyższego):

Kod:

lista2 = []

for i in lista:

  lista2.append(i.split("."))

page_footer = "Pisz do mnie pod: " + " (kropka) ".join(lista2[0]) + " (małpa) " + \

  " (kropka) ".join(lista2[1])

print page_footer

 

 

fraza = "to be or not to be -- that is the question"

print "Napis", "\"" + fraza + "\"", "zawiera", len(set(fraza.split())), "różnych słów."

 

liczby = ["3", "4", "1", "10"]

print "+".join(liczby)

Teraz funkcja sum() – bardzo prosta i intuicyjna, zwraca sumę liczb w przekazanej sekwencji (liście lub krotce).  Przykłady:

Kod:

 

sum([1, 3.5, -2])

sum((1, 3.5, -2))  # ale nie tak: sum(1, 3.5, -2)

sum(range(3, 6))

sum([3+2j, 1+1j, 5])

Oczywiście sum nie służy do konkatenacji stringów na liście (od tego przecież jest join()).





Funkcja wbudowana map(f, sekw) przykłada funkcję f do kolejnych elementów sekwencji sekw i zwraca nową sekwencję o tej samej długości co sekw.  Prosty przykład:

Kod:

 

lista = map(len, ["To", "są", "elementy", "listy"])

print lista  # wyświetli [2, 2, 8, 5]

Powiedzmy, że chcemy mieć na liście pierwiastki kolejnych liczb całkowitych od 1 do 10.  Piszemy:


Kod:

import math

we = range(1, 11)

wy = map(math.sqrt, wy)  # obejrzyj wy

Można też krócej:

Kod:

import math

wy = map(math, sqrt, range(1, 11))

Czy można użyć własnej funkcji?  Oczywiście.  Powiedzmy, że chcemy zrobić działanie odwrotne, tj. wyprodukować kwadraty elementów listy (np. nadal 1..10).  Piszemy:

Kod:

 

def kwadrat(x):

  return x*x

 

wy = map(kwadrat, range(1, 11))

Proste, ale trochę człowieka irytuje, że dla tak błahego celu trzeba było pisać osobną funkcję.  Na szczęście wcale nie trzeba.  Można wykorzystać tzw. funkcję anonimową – najpierw przykład:


Kod:

wy = map(lambda x: x*x, range(1, 11))

Ogólnie w funkcjach anonimowych po słowie lambda podaje się argumenty funkcji, ale w tym przypadku, przy map, funkcja jest 1-argumentowa.  Po dwukropku jest zwracane wyrażenie, czyli wszystko, o co nam chodzi.



Chcemy napisy na liście skrócić do pierwszych 2 liter – nic prostszego:

Kod:

pory_roku = ["wiosna", "lato", "jesień", "zima"]

pory_skrót = map(lambda s: s[:2], pory_roku)

print pory_skrót

A może „rozstrzelić” napis, wstawiając 2 spacje po każdej literce?

Kod:

s1 = "abrakadabra"

s2 = "".join(map(lambda ch: ch+"  ", s1))

print s2

Ostatni przykład był ciut bardziej skomplikowany: wyjściem map jest wszak lista, więc trzeba ją dopiero skleić w string – dlatego join(), a łącznikiem string pusty.



Niestety, ten przykład był z kategorii overkill: to samo można było osiągnąć prościej, wymieniając kluczową linię na

Kod:

s2 = "  ".join(list(s1))

To samo?  Hm, nie do końca – odpowiedz, dlaczego napisy s2 w obu przypadkach (nieco) się różnią.



Inny przykład: chcemy spacje w stringu s1 zastąpić znakami podkreślenia:

Kod:

s2 = "".join(map(lambda ch: "_" if ch==" " else ch, s1))

Tu wszedł nowy element: wyrażenie trójkowe (dopiero od wersji 2.5 Pythona).  Składnia: wartość1 if warunek else wartość2.  Przy funkcjach anonimowych konstrukcja jak znalazł.



Częste wykorzystanie map to hurtowa konwersja liczb na napisy lub odwrotnie:

Kod:

li_int = [4, 10, 18, 6, 200]

li_str = map(str, li_int)

for i in li_str:

  print i.rjust(6)

Powtórzmy, bo ważne: map zwraca nową sekwencję (dokładniej listę), nie modyfikuje starej.





Powiedzieliśmy, że map zachowuje długość sekwencji oryginalnej.  Czasem jednak chcemy ją skrócić, odfiltrować.  Innymi słowy, zostawić tylko te elementy, które spełniają jakieś kryterium.  Mamy do tego w Pythonie funkcję filter:

Kod:

 

print filter(lambda x: x>10, [2, 4, 20, 5, 10])  # na zwróconej liście jest tylko [20]

 

s = "Adam Mickiewicz jest autorem Dziadów i Świtezianki"

# wypisz słowa z wielkiej litery

li = filter(lambda w: w[0].isupper(), s.split())

print li  # możesz zmienić na ładniejszą postać wypisywania

Słownik zawiera pary: osoba, roczny dochód.  Chcemy policzyć średnią dochodu tylko wśród osób, których dochód przekracza 100 tys.  Nietrudne:

Kod:

dane = { "Bjarne Stroustrup": 800000, "Harry Jones": 35000, "Jan Kowalski": 84000, \

  "John Silverberg": 120000 }

dochody = map(lambda i: dane[i], dane)  # i – klucz, dane[i] – skojarzona z nim wartość

odfiltrowane = filter(lambda forsa: forsa > 100000, dochody)

print float(sum(odfiltrowane)) / len(odfiltrowane)

 

pliki = ["dane.dat", "yeyeye.mp3", "winword.exe", "jazz01.MP3", "La Cucaracha.mp3"]

empetrójki = filter(lambda s: s.lower().endswith(".mp3"), pliki)

print empetrójki

Oczywiście, można też pisać trochę bardziej rozwlekle:

Kod:

empetrójki = filter(lambda s: s.lower().endswith(".mp3") == True, pliki)

A zatem inne pliki otrzymamy poprzez:

Kod:

pozostałe = filter(lambda s: s.lower().endswith(".mp3") == False, pliki)

albo też

Kod:

pozostałe = filter(lambda s: not s.lower().endswith(".mp3"), pliki)

Funkcja filter zastosowana na stringu zwróci string (a nie listę, jak przy map).  Podobnie z krotką.





I wreszcie reduce, stosunkowo rzadko używane, ale czasem wygodne.  Tym razem przykładamy funkcję dwuargumentową: najpierw do dwóch pierwszych elementów sekwencji, potem pierwszym argumentem jest otrzymany wynik, a drugim – trzeci element sekwencji, itd. do końca sekwencji.  Brzmi mętnie?  No to przykłady:

Kod:

 

silnia = reduce(lambda a, b: a*b, range(1, 7))  # 6!

binarne_OR = reduce(lambda a, b: a | b, [1, 4, 16, 3])

Powiedzmy, że (inspiracja wzięta z książki „Beginning Python” M. L. Hetlanda) studentowi I roku informatyki chcemy zademonstrować najbardziej podstawowe algorytmy i konstrukcje programistyczne.  Jednym z klasycznych zadań jest szukanie maksimum w sekwencji (np. tablicy) liczb.  Chcemy nie tylko dać końcową odpowiedź, ale pokazać krok po kroku, jak zmienia się ów max w trakcie szukania.  Oto stosowny kod Pythona:

Kod:

 

def max_z_podglądem(a, b):

  print "szukam większej liczby z pary", a, "oraz", b, "; jest nią", max(a, b)

  return max(a, b)  # tak, jest gotowa funkcja max w Pythonie, podobnie jak i min

 

print reduce(max_z_podglądem, [3, 1, 3, 9, 4, 11, 6, 12, 13, -2])

20.Dana jest lista liczb zespolonych.  Możliwie prosto (1 linijka!) wyprodukuj listę modułów tych liczb, oczywiście w tej samej kolejności.  Wskazówka: dla liczb zespolonych do części rzeczywistej i urojonej odwołujemy się przez pola real, imag.

21.Wczytaj od użytkownika listę 7 imion (każdy wpis zakończony Enterem), a następnie wypisz na ekran tylko te wpisy, które rzeczywiście mogą być imionami, to znaczy: pojedyńcze wyrazy, pisane z wielkiej litery, pozostałe litery małe.  Wskazówka: metoda capitalize() dla stringów może się przydać.

22.Napisz funkcję o 1-linijkowym ciele zwracającą listę dzielników dodatnich argumentu będącego liczbą dodatnią.  Wariant nieco trudniejszy (choć niekoniecznie w jednej linii): argument wejściowy może też być liczbą ujemną (zakładamy, że ma wtedy tylko dzielniki ujemne).

23.Napisz funkcję sprawdzającą, czy dana liczba dodatnia jest liczbą doskonałą (tj. jest sumą swych dzielników właściwych, np. 6 = 1 + 2 + 3).  Przetestuj tę funkcję na wszystkich liczbach od 1 do 10000.

24.Dany jest napis s = "to jest 14-ta próba napisania tego programu, a miały być tylko 4 !!!".  Zwróć konkatenację samych cyfr z tego napisu, w kolejności.  Wskazówka: metoda s.isdigit().


http://img208.imageshack.us/img208/623/mnd1.jpg
http://images.cooltext.com/3860851.png

Offline

 

Stopka forum

RSS
Powered by PunBB
© Copyright 2002–2008 PunBB
Polityka cookies - Wersja Lo-Fi

[ Generated in 0.013 seconds, 7 queries executed ]


Darmowe Forum | Ciekawe Fora | Darmowe Fora
www.sgaming.pun.pl www.chemiaumcs.pun.pl www.chomiki-pbf.pun.pl www.talesofshinobi.pun.pl www.djronnie.pun.pl