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

Zagnieżdżanie tupli i list a następnie odczytywanie konkretnych elementów

Object Storage Arubacloud
+2 głosów
546 wizyt
pytanie zadane 20 października 2021 w Python przez KerivePL Początkujący (310 p.)

W jestem w martwym punkcie mojego programu. Chciałem przeanalizować dodawane utwory na czacie discordowym. Już udało mi się to osiągnąć, ale aby nie osiąść na laurach postanowiłem się oddać podstawowemu przeanalizowaniu danych. Chciałem zacząć od zliczenia ile razy leciał dany utwór.

 

Funkcja dostaje dane w postaci tupla wielokrotnie zagnieżdżonego, każdy element 'głównego tupla' zawiera jedno odtworzenie konkretnego utworu (tytuł wraz z datą i godziną, kiedy do tego doszło).

#budowa tupla
(

(utwór1, ( data_dodania, (godzina, AM / PM )))

(utwór2, ( data_dodania, (godzina, AM / PM )))

(etc.)
)

Czyli właściwie, jakbym chciał podliczyć ile razy utwór wystąpił to mógłbym stworzyć nową listę do której powrzucam same tytuły utworów i potem łatwo to wyliczyć. Ale wydaje mi się że to będzie dość na skróty, zamiast uzyskać pomoc w dręczącym mnie problemie.

Chciałbym zrobić coś w stylu:

#data = powyższy tuple
tracks_stats= [ ]
for i in data:
    if not i in tracks_stats:
        tracks_stats.append ( [ i, data.count ( i ) ] )

Pomysł prosty jak budowa cepa, ale przecież element 'i' w 'data' nie jest samą nazwą tylko zagnieżdżonym tuplem. Chciałbym aby zamiast całego tupla patrzeć tylko na pierwszą część jego elementów.

Tak samo chciałbym aby podczas sprawdzania czy elementu nie ma w liście 'tracks_stats' patrzeć tylko na pierwsze elementy tejże listy.
Jest to w ogóle możliwe? Przeczucie mówi mi że lambda, którą stosuje się często przy sortowaniu list zagnieżdżonych tutaj może pomóc, ale nie mam pojęcia jak (prawdopodobnie wynika to z niedostatecznego zrozumienia również tego zagadnienia).

Przepraszam za być może niezrozumiałe opisanie problemu, ale jestem samoukiem i moja wiedza jesz kompletnie niekompletna.
Z góry dziękuję za udzieloną pomoc, pomimo przeszkody jaką była długość tego posta.

2 odpowiedzi

+2 głosów
odpowiedź 21 października 2021 przez edutomek Dyskutant (8,380 p.)

To tak bez deklarowania klas, zakładając, że naprawdę mamy do czynienia z taką krotką, jaka została przedstawiona, licząc "na piechotę":

#data = powyższy tuple
tracks_stats= {}
for i, _ in data:
  if i not in tracks_stats:
    tracks_stats[i] = 1
  else:
    tracks_stats[i] = tracks_stats[i] + 1

Wersja ze wspomnianym przez Benka Counterem:

tracks_stats = Counter([i[0] for i in data])

Żadnej z wersji nie testowałem, podaję tylko "zajawkę" kodu.

Gdyby się okazało, że w krotce z danymi mamy różne krotki reprezentujące utwory (np. 2-, 3- elementowe), to trzeba byłoby to uwzględnić w ciele pętli, zamiast w for.

komentarz 23 października 2021 przez KerivePL Początkujący (310 p.)
Dzięki za pomoc. Zupełnie zapomniałem o takiej specyfice słowników, racja można to wykorzystać aby wszystko ładnie zadziałało.
Niemniej jestem ciekawy czy dałoby się rozwiązać problem na samych listach / tuplach , wydaje mi się że jest to 'jakoś' do zrobienia w krótki sposób, ale niestety mam jeszcze za małą wiedzę.
komentarz 24 października 2021 przez edutomek Dyskutant (8,380 p.)

W sumie by się dało, choć kombinowania byłoby więcej.

Taka koncepcja:

1) Bierzesz nazwę utworzu z pierwszego elementu z kolekcji danych (nie ma znaczenia, czy kolekcja to krotka, czy lista).
2) Tworzysz nową listę, na której pozostawiasz tylko te elementy, których nazwa jest inna. (Można zastosować np. list comprehension.)
3) Porównując rozmiary początkowej i końcowej listy wiesz, ile jest powtórzeń utworu.
4) Dopóki lista z punktu 2 nie jest pusta, powtarzasz całość jeszcze raz (z tą nową listą).

Czyli mamy coś takiego (znowu - nie testowałem kodu, piszę "z palca"):

tracks_stats = []
while len(data) > 0:
  name, _ = data[0]
  len_0 = len(data)
  data = [i for i in data if i[0] != name]
  len_1 = len(data)
  tracks_stats.append( (name, len_0 - len_1) )

Na końcu mam listę dwójek (nazwa utworu, liczba wystąpień). W sumie trudniejsze to chyba do wyszukania danych, niż słownik. Ale nie wiem, co potem robisz z tymi danymi - może wcale nie wyszukujesz?

+1 głos
odpowiedź 20 października 2021 przez Benek Szeryf (90,870 p.)

Z mojego doświadczenia, jeśli w Pythonie używasz więcej niż 2 typów zagnieżdżonych, to warto pomyśleć o refaktoryzacji. Najprościej stworzyć klasę reprezentującą utwór. Jeśli natomiast chcesz coś zliczać, to warto poczytać o obiekcie Counter.

Podobne pytania

0 głosów
1 odpowiedź 163 wizyt
pytanie zadane 21 października 2020 w Python przez cba Użytkownik (620 p.)
0 głosów
1 odpowiedź 452 wizyt
0 głosów
1 odpowiedź 1,348 wizyt
pytanie zadane 24 listopada 2018 w Python przez Maciej Złotorowicz Gaduła (4,230 p.)

92,555 zapytań

141,402 odpowiedzi

319,538 komentarzy

61,938 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!

...