• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Jak odwołać się do obiektu o podanym polu

Object Storage Arubacloud
0 głosów
231 wizyt
pytanie zadane 15 kwietnia 2020 w Python przez manjaro Nałogowiec (37,390 p.)

Mam taki kod

class Student(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def hello(self):
        print("Hello, my name is",self.name,"and I have",self.age,"years old")

students = []
students.append(Student("John", 30))
students.append(Student("Bob", 25))
students.append(Student("Amy", 20))

students[1].hello()

Problem polega na tym że chcę aby np student o imieniu John się przedstawił a nie wiem (bo skąd?) jaki on ma indeks w liście... Jak to zrobić efektywnie bo rozumiem że wyszukiwanie w pętli studenta wg jakiegoś kryterium jest co najmniej śmieszne ;)

A może cały ten mój kod jest niewłaściwy i w inny sposób trzeba to zrobić? Np nie umieszczać studentów w liście tylko w innym kontenerze? Njprościej bym to zrobił z użyciem bazy danych ale ma to być bez bazy.

select * from student where name='John'

Istnieje takie zapytanie w pythonie do listy?

komentarz 15 kwietnia 2020 przez Benek Szeryf (91,010 p.)
W kontekście tego co napisałeś w komentarzach, to wygląda na problem XY.
komentarz 15 kwietnia 2020 przez manjaro Nałogowiec (37,390 p.)

Możesz to sprecyzować, bo nie bardzo wiem o co Ci chodzi?

Generalnie chodzi mi o to jak zbudawać taką bazę studentów aby w jednoznaczny sposób móc ich później wyszukiwać...

A w zasadzie to chodziło mi bardziej o wskazanie jak to zrobić prawidłowo, bo zrobić byle jak i mało optymalnie to potrafię.

komentarz 15 kwietnia 2020 przez Benek Szeryf (91,010 p.)

Generalnie chodzi mi o to jak zbudawać taką bazę studentów aby w jednoznaczny sposób móc ich później wyszukiwać...

Masz wiele możliwości. Jak chcesz mieć unikalne rekordy, to pewnie potrzebujesz jakiejś bazy danych z kluczem głównym. Wszystko zależy ile tych danych masz. Jak bardzo chcesz pokombinować, to możesz stworzyć sobie słownik z odpowiednimi polami (imię, nazwisko, pesel) i jedno z unikalnym kluczem. Albo może najprościej wykorzystać sqlite3.

komentarz 15 kwietnia 2020 przez manjaro Nałogowiec (37,390 p.)
W tym konkretnym projekcie mają być obiekty i nie ma być baz danych ani plików. Jakbym nie miał narzuconych metod działania to bym to oczywiście zrobił na SQL

2 odpowiedzi

+2 głosów
odpowiedź 15 kwietnia 2020 przez Benek Szeryf (91,010 p.)
edycja 15 kwietnia 2020 przez Benek

No to może tak:

class Student:

    def __init__(self, name: str, age: int) -> None:
        self.name = name
        self.age = age

    def __str__(self) -> str:
        return f'Hello, my name is {self.name} and I am {self.age} years old'


if __name__ == '__main__':
    students = []
    students.append(Student('John', 30))
    students.append(Student('Bob', 25))
    students.append(Student('Amy', 20))

    s = {s.name:s for s in students}
    print(s.get('John'))

Przy czym wypadałoby, by klucz był unikalny. W przeciwnym razie rekordy o tym samym kluczu zostaną nadpisane.

1
komentarz 15 kwietnia 2020 przez manjaro Nałogowiec (37,390 p.)
Dzięki Benek, chyba z tego skorzystam.
+1 głos
odpowiedź 15 kwietnia 2020 przez LuQ232 Mądrala (7,200 p.)
edycja 15 kwietnia 2020 przez LuQ232

Według mnie przeszukanie listy nie jest złym pomysłem. Będzie to złożoność liniowa O(n) gdzie n to liczba studentów. To rozwiązanie jest o tyle dobre, że może być kilku uczniów o tym samym imieniu. Wtedy każdy z nich po kolei się przedstawi.

for student in students:
    if student.name =="John":
        student.hello()

 

Również możesz przefiltrować listę. W tym przypadku obiekty klasy student których imie to John będziemy przetrzymywać w liście o nazwie matches.

matches = [elem for elem in students if elem.name=="John"]

 Następnie na każdym obiekcie w liście matches wywołasz metodę hello.

 

Odnośnie indeksowania:

a nie wiem (bo skąd?) jaki on ma indeks w liście...

Przy przeszukaniu jak poniżej indeks danego obiektu w liście jest dostępny w zmiennej index.

for index, student in enumerate(students):
    if student.name == "John":
        student.hello()
        print(index)

 

1
komentarz 15 kwietnia 2020 przez manjaro Nałogowiec (37,390 p.)

Dziękuję Ci za poświęcony czas i sugestie, ale jakoś nie jestem przekonany że to najbardziej elegancki sposób.

Przyszło mi do głowy inne rozwiązanie jeszcze ale czy lepsze... Trzymać obiekty w słownikach zamiast listach, gdzie kluczem byłoby coś unikatowego najlepiej pesel. Tutaj akurat kluczem jest imię ale to tylko przykład.

students = {}
students["John"] = Student("John", 30)


print(students.get("John").hello())

 

komentarz 15 kwietnia 2020 przez LuQ232 Mądrala (7,200 p.)
Jeżeli każdy obiekt miałby coś unikatowego to jest to całkiem dobre rozwiązanie. Jednak nie mi podejmować decyzję co jest najlepsze ;). Przy imionach niestety nie mamy tego unikatowego klucza
1
komentarz 15 kwietnia 2020 przez Benek Szeryf (91,010 p.)
print(students.get("John").hello())

A czym to się różni od tych linii poniżej?

if student.name == "John":
select * from student where name='John'

Masz tylko przykrycie tego samego innym interfejsem. Przecież w metodzie słownikowej gdzieś pod spodem też jest IF. Równie dobrze możesz sobie zdefiniować swoją funkcję:

def say_hello(name, students):
    [student.hello() for student in students if student.name == name]

I wywołać:

say_hello('John', students)

 

komentarz 15 kwietnia 2020 przez manjaro Nałogowiec (37,390 p.)
Tuytaj to bym polemizował.

Bo z tego co wiem (choć mogę się mylić) to sql przeszukuje binarnie baze a nie liniowo.

Natomiast wykorzystanie słownika daje dostęp O(1) a nie O(n)

Podobne pytania

0 głosów
1 odpowiedź 477 wizyt
pytanie zadane 4 kwietnia 2020 w Python przez manjaro Nałogowiec (37,390 p.)
0 głosów
1 odpowiedź 616 wizyt
pytanie zadane 17 lutego 2018 w PHP przez Przemysław Obywatel (1,510 p.)

92,579 zapytań

141,429 odpowiedzi

319,657 komentarzy

61,962 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...