Mam następujący kod, aby to zrobić, ale jak mogę to zrobić lepiej? W tej chwili myślę, że to lepsze niż zagnieżdżone pętle, ale zaczyna mieć Perl-one-linerish, gdy masz generator w zrozumieniu listy.
day_count = (end_date - start_date).days + 1
for single_date in [d for d in (start_date + timedelta(n) for n in range(day_count)) if d <= end_date]:
print strftime("%Y-%m-%d", single_date.timetuple())
Notatki
- Nie używam tego do drukowania. To tylko do celów demonstracyjnych.
start_date
Iend_date
zmiennedatetime.date
obiektów, ponieważ nie muszę timestampów. (Zostaną wykorzystane do wygenerowania raportu).
Przykładowe dane wyjściowe
Dla daty początkowej 2009-05-30
i końcowej 2009-06-09
:
2009-05-30
2009-05-31
2009-06-01
2009-06-02
2009-06-03
2009-06-04
2009-06-05
2009-06-06
2009-06-07
2009-06-08
2009-06-09
Odpowiedzi:
Dlaczego są dwie zagnieżdżone iteracje? Dla mnie tworzy tę samą listę danych z tylko jedną iteracją:
I żadna lista nie jest przechowywana, tylko jeden generator jest iterowany. Także „if” w generatorze wydaje się niepotrzebne.
W końcu sekwencja liniowa powinna wymagać tylko jednego iteratora, a nie dwóch.
Zaktualizuj po dyskusji z Johnem Machinem:
Być może najbardziej eleganckim rozwiązaniem jest użycie funkcji generatora, aby całkowicie ukryć / wyodrębnić iterację w zakresie dat:
Uwaga: Aby zachować spójność z wbudowaną
range()
funkcją, iteracja zatrzymuje się przed osiągnięciemend_date
. Tak więc w celu włączenia iteracji użyj następnego dnia, tak jak zrobiłbyś torange()
.źródło
(start_date + datetime.timedelta(n) for n in range((end_date - start_date).days))
Może to być bardziej jasne:
źródło
Użyj
dateutil
biblioteki:Ta biblioteka Pythona ma wiele bardziej zaawansowanych funkcji, z których niektóre są bardzo przydatne, takie jak
relative delta
s - i jest zaimplementowana jako pojedynczy plik (moduł), który łatwo można dołączyć do projektu.źródło
until
natomiast ostateczna datadaterange
metody w odpowiedzi Bera jest wyłącznym odend_date
.Pandy świetnie nadają się do szeregów czasowych i mają bezpośrednie wsparcie dla zakresów dat.
Następnie można zapętlić pętlę, aby wydrukować datę:
Ma również wiele opcji ułatwiających życie. Na przykład, jeśli chcesz tylko dni powszednie, po prostu zamienisz na bdate_range. Zobacz http://pandas.pydata.org/pandas-docs/stable/timeseries.html#generating-ranges-of-timestamps
Moc Pandas to tak naprawdę ramki danych, które obsługują operacje wektoryzowane (podobnie jak numpy), dzięki czemu operacje na dużych ilościach danych są bardzo szybkie i łatwe.
EDYCJA: Możesz również całkowicie pominąć pętlę for i po prostu wydrukować ją bezpośrednio, co jest łatwiejsze i bardziej wydajne:
źródło
Ta funkcja robi więcej niż jest to ściśle wymagane, obsługując krok ujemny itp. Tak długo, jak uwzględnisz logikę zakresu, nie potrzebujesz osobnego
day_count
i, co najważniejsze, kod staje się łatwiejszy do odczytania, gdy wywołujesz funkcję z wielu miejsca.źródło
To najbardziej czytelne dla człowieka rozwiązanie, jakie mogę wymyślić.
źródło
Dlaczego nie spróbować:
źródło
arange
Funkcję Numpy można zastosować do dat:Zastosowanie
astype
to do konwersjinumpy.datetime64
na tablicędatetime.datetime
obiektów.źródło
dates = np.arange(d0, d1, dt).astype(datetime.datetime)
Pokaż ostatnie n dni od dzisiaj:
Wynik:
źródło
print((datetime.date.today() + datetime.timedelta(i)).isoformat())
print((datetime.date.today() + datetime.timedelta(i)))
bez .isoformat () daje dokładnie taki sam wynik. Potrzebuję mojego skryptu, aby wydrukować RRMMDD. Czy ktoś wie jak to zrobić?d = datetime.date.today() + datetime.timedelta(i); d.strftime("%Y%m%d")
źródło
źródło
Dla kompletności Panda ma również
period_range
funkcję znaczników czasu, które są poza zakresem:źródło
Mam podobny problem, ale muszę iterować co miesiąc zamiast codziennie.
To jest moje rozwiązanie
Przykład 1
Wynik
Przykład nr 2
Wynik
źródło
Czy
„t* uwierzyć to pytanie istnieje od 9 lat i nikt nie sugeruje prostą funkcję rekurencyjną:Wynik:
Edycja: * Teraz mogę w to uwierzyć - zobacz Czy Python optymalizuje rekurencję ogona? . Dziękuję Tim .
źródło
Możesz wygenerować serię dat między dwiema datami, korzystając z biblioteki pand w prosty i godny zaufania sposób
Możesz zmienić częstotliwość generowania dat, ustawiając częstotliwość jako D, M, Q, Y (dzienna, miesięczna, kwartalna, roczna)
źródło
źródło
Ta funkcja ma kilka dodatkowych funkcji:
sprawdzanie błędów, jeśli koniec jest starszy niż początek
źródło
Oto kod ogólnej funkcji zakresu dat, podobny do odpowiedzi Ber, ale bardziej elastyczny:
źródło
Co z następującymi czynnościami dotyczącymi zakresu zwiększanego o dni:
W przypadku wersji ogólnej:
Zauważ, że .total_seconds () jest obsługiwany tylko po Pythonie 2.7. Jeśli utkniesz we wcześniejszej wersji, możesz napisać własną funkcję:
źródło
Nieco inne podejście do odwracalnych kroków poprzez przechowywanie
range
argumentów w krotce.źródło
WYNIK:
źródło