przypuśćmy, że mam wiele owoców w różnych kolorach, np. 24 niebieskie banany, 12 zielonych jabłek, 0 truskawek i tak dalej. Chciałbym uporządkować je w strukturę danych w Pythonie, która pozwala na łatwe wybieranie i sortowanie. Moim pomysłem było umieszczenie ich w słowniku z krotkami jako kluczami, np.
{ ('banana', 'blue' ): 24,
('apple', 'green'): 12,
('strawberry','blue' ): 0,
...
}
czy nawet słowniki, np.
{ {'fruit': 'banana', 'color': 'blue' }: 24,
{'fruit': 'apple', 'color': 'green'}: 12,
{'fruit': 'strawberry','color': 'blue' }: 0,
...
}
Chciałbym na przykład pobrać listę wszystkich niebieskich owoców lub bananów we wszystkich kolorach lub posortować ten słownik według nazwy owocu. Czy są sposoby, aby to zrobić w czysty sposób?
Może się zdarzyć, że słowniki z kluczami krotek nie są właściwym sposobem radzenia sobie z taką sytuacją.
Wszystkie sugestie mile widziane!
Odpowiedzi:
Osobiście jedną z rzeczy, które uwielbiam w Pythonie, jest kombinacja tuple-dict. To, co tu masz, to w rzeczywistości tablica 2d (gdzie x = nazwa owocu, a y = kolor), a ja generalnie jestem zwolennikiem zasady krotek do implementacji tablic 2d, przynajmniej jeśli coś takiego
numpy
lub baza danych nie jest bardziej odpowiednie . Krótko mówiąc, myślę, że masz dobre podejście.Zauważ, że nie możesz używać dykt jako kluczy w dyktacie bez dodatkowej pracy, więc nie jest to zbyt dobre rozwiązanie.
To powiedziawszy, powinieneś również rozważyć namedtuple () . W ten sposób możesz to zrobić:
Teraz możesz użyć swojej dyktowania fruitcount:
Inne sztuczki:
Powtarzając chmullig, aby otrzymać listę wszystkich kolorów jednego owocu, należałoby przefiltrować klucze, tj
źródło
name='banana'
?bananas = filter(lambda fruit: fruit.name=='banana', fruits)
Lubbananas = [fruit for fruit in fruits if fruit.name=='banana']
. Jest to jeden ze sposobów, dzięki którym zagnieżdżone dykty są potencjalnie bardziej wydajne; wszystko sprowadza się do sposobu, w jaki planujesz wykorzystać dane.count
Najlepszym rozwiązaniem będzie utworzenie prostej struktury danych w celu zamodelowania tego, co masz. Następnie możesz przechowywać te obiekty na prostej liście i sortować / pobierać je w dowolny sposób.
W tym przypadku użyłbym następującej klasy:
Następnie możesz po prostu skonstruować instancje „Owoce” i dodać je do listy, jak pokazano w następujący sposób:
Prosta lista
fruits
będzie znacznie łatwiejsza, mniej zagmatwana i lepiej utrzymana.Kilka przykładów użycia:
Wszystkie poniższe dane wyjściowe to wynik po uruchomieniu podanego fragmentu kodu, po którym następuje:
Niesortowana lista:
Wyświetlacze:
Posortowane alfabetycznie według nazwy:
Wyświetlacze:
Posortowane według ilości:
Wyświetlacze:
Gdzie kolor == czerwony:
Wyświetlacze:
źródło
Baza danych, dict of dicts, słownik listy słowników, nazwana krotka (to podklasa), sqlite, redundancy ... Nie wierzyłem własnym oczom. Co jeszcze ?
Tak! myślałem
Tak więc, moim zdaniem, wystarczy lista krotek:
wynik
źródło
Słownik prawdopodobnie nie jest tym, czego powinieneś używać w tym przypadku. Bardziej funkcjonalna biblioteka byłaby lepszą alternatywą. Prawdopodobnie prawdziwa baza danych. Najłatwiejszy byłby sqlite . Możesz zachować całość w pamięci, przekazując ciąg ': memory:' zamiast nazwy pliku.
Jeśli chcesz kontynuować tę ścieżkę, możesz to zrobić z dodatkowymi atrybutami w kluczu lub wartości. Jednak słownik nie może być kluczem do innego słownika, ale krotka może. Dokumenty wyjaśniają, co jest dozwolone. Musi to być niezmienny obiekt, który zawiera łańcuchy, liczby i krotki, które zawierają tylko łańcuchy i liczby (i więcej krotek zawierających tylko te typy rekurencyjnie ...).
Możesz zrobić swój pierwszy przykład
d = {('apple', 'red') : 4}
, ale bardzo trudno będzie zapytać o to, czego chcesz. Musisz zrobić coś takiego:źródło
W przypadku kluczy jako krotek po prostu filtrujesz klucze z podanym drugim składnikiem i sortujesz go:
Sortowanie działa, ponieważ krotki mają naturalną kolejność, jeśli ich składniki mają naturalną kolejność.
Gdy klucze są raczej pełnoprawnymi obiektami, po prostu filtrujesz je według
k.color == 'blue'
.Tak naprawdę nie możesz używać dykt jako kluczy, ale możesz utworzyć najprostszą klasę
class Foo(object): pass
i dodawać do niej dowolne atrybuty w locie:Te instancje mogą służyć jako klucze dyktowania, ale uważaj na ich zmienność!
źródło
Możesz mieć słownik, w którym wpisy są listą innych słowników:
Wynik:
Edycja: jak wskazał eumiro, możesz użyć słownika słowników:
Wynik:
źródło
Ten typ danych jest efektywnie pobierany ze struktury danych podobnej do Trie. Pozwala również na szybkie sortowanie. Wydajność pamięci może jednak nie być tak duża.
Tradycyjna trie przechowuje każdą literę słowa jako węzeł w drzewie. Ale w twoim przypadku twój „alfabet” jest inny. Przechowujesz łańcuchy zamiast znaków.
może wyglądać mniej więcej tak:
zobacz ten link: trie in python
źródło
Chcesz używać dwóch klawiszy niezależnie, więc masz dwie możliwości:
Przechowuj dane redundantnie za pomocą dwóch dykt jako
{'banana' : {'blue' : 4, ...}, .... }
i{'blue': {'banana':4, ...} ...}
. Wtedy wyszukiwanie i sortowanie jest łatwe, ale musisz upewnić się, że zmodyfikujesz dykty razem.Przechowuj to tylko jeden dykt, a następnie napisz funkcje, które będą po nich iterować, np .:
źródło