trzeba zrozumieć różnicę między range(0,2)
i list(range(0,2))
korzystając python2.7Jaka jest różnica między "zakresem (0,2)" i "listą (zakres (0,2))"?
Zarówno zwróci listę więc co dokładnie jest różnica?
trzeba zrozumieć różnicę między range(0,2)
i list(range(0,2))
korzystając python2.7Jaka jest różnica między "zakresem (0,2)" i "listą (zakres (0,2))"?
Zarówno zwróci listę więc co dokładnie jest różnica?
w Pythonie 3.x
range(0,3)
zwraca klasę niezmiennych iterowalny obiektów, które umożliwia iteracyjne nad nimi, nie produkują listy, a oni nie przechowywać wszystkie elementy w zakresie pamięci, zamiast oni wytwarzają elementy w locie (tak jak je przeglądasz), podczas gdy list(range(0,3))
tworzy listę (przez powtarzanie wszystkich elementów i dołączanie do listy wewnętrznie).
Przykład -
>>> range(0,3)
range(0, 3)
>>> list(range(0,3))
[0, 1, 2]
Idealnie, jeśli tylko chcesz iteracyjne nad tym przedziale wartości, range(0,3)
byłoby szybciej niż (list(range(0,3))
ponieważ ten ostatni ma napowietrznej produkujących listę przed rozpoczęciem iteracji nad nim.
w Pythonie 2.x, range(0,3)
tworzy listę, a nie my również mieliśmy xrange()
funkcję, która ma podobne zachowanie range()
funkcji z Pythona 3.x (XRange został przemianowany na klasy w Pythonie 3.x)
dla Pythona 3.5, z documentation -
obiektów klasy uruchomienie systemu collections.abc.Sequence ABC i oferują funkcje takie jak testy obudowy, odnośnika indeksu elementu, krojenie i wsparcia dla indeksów ujemnych
Więc można robić takie rzeczy -
>>> range(0,10)[5]
5
>>> range(0,10)[3:7]
range(3, 7)
>>> 5 in range(6,10)
False
>>> 7 in range(1,8)
True
a wszystkie te operacje są stałe w czasie, jak widać z tego testu -
In [11]: %timeit a = xrange(0,1000000)[1000]
1000000 loops, best of 3: 342 ns per loop
In [12]: %timeit a = xrange(0,1000000)[10000]
1000000 loops, best of 3: 342 ns per loop
In [13]: %timeit a = xrange(0,1000000)[100000]
1000000 loops, best of 3: 342 ns per loop
In [14]: %timeit a = xrange(0,1000000)[999999]
1000000 loops, best of 3: 342 ns per loop
In [15]: %timeit a = xrange(0,10000000)[9999999]
1000000 loops, best of 3: 339 ns per loop
In [16]: %timeit a = xrange(0,1000000000000)[9999999999]
1000000 loops, best of 3: 341 ns per loop
To zależy od wersji Pythona, z której korzystasz.
W języku Python 2.x, range()
zwraca listę, więc są one równoważne.
W języku Python 3.x, zwraca niezmienny typ sekwencji, aby uzyskać listę, trzeba uzyskać list(range(0,2))
.
Faktycznie 'zasięg' nie zwraca generatora, jest to obiekt niezmienny. Spróbuj wykonać 'next (zakres (0,5))'. Zrozumiesz. –
@AnandSKumar Poprawione teraz. –
W python3.x, ma swój zakres typ
>>> range(1)
range(0, 1)
>>> type(range(1))
<class 'range'>
Więc jeśli chcesz użyć zasięgu() w pętli for, to jest w porządku. Jednak nie można go użyć jako obiektu listy jako purely
. Aby to zrobić, musisz przekonwertować go na listę.
python2 przykład:
>>> L = range(10)
>>> L[::-1]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Python3 przykład:
>>> L = range(10)
>>> L[::-1]
range(9, -1, -1)
Możesz wycinać zakres - '>>> zakres (0,3) [1: 3] zakres (1, 3)' –
Jak @AnandSKumar wskazuje w swojej odpowiedzi, python3 'range()' jest typem sekwencji i ma te same operacje co listy i krotki (z wyjątkiem konkatencji i powtórzeń) https://docs.python.org/3/library/stdtypes.html#sequence-types-list-tuple-range – Scott
@Anand, masz rację krojenie, które na nim działa. Zaktualizowałem swoją odpowiedź na to, co miałem na myśli. Dzięki! –
Oba polecenia listy powrót w Python2.x. Ale w zakresie Python3.x jest niezmienna sekwencja i nie zwraca listy. Służy do iteracji pętli reklamowych
Zasadniczo różnica polega na tym, że range(0, 2)
jest funkcją generatora, a list(range(0, 2))
jest faktyczną listą.
Funkcja generatora jest używana w pętlach. Na przykład funkcja generatora pliku odczytuje bardzo duży plik wiersz po linii.
def gen():
for line in open("hugefile.csv", "r"):
yield line #Gives back the line every time it is read, but forgets that line after
for line in gen():
print(line)
Spowoduje to wydrukowanie każdej linii bez przeciążania pamięci RAM komputera, ponieważ czyta się tylko jeden po drugim w obu funkcjach. Jeśli jednak zrobimy coś takiego, jak
def readEntireFile():
return [line for line in open("hugefile.csv", "r")] #Python has lazy ways of making lists, this is the same as returning a list with all the lines in the file
for line in readEntireFile():
print(line)
Druga część wygląda tak samo, ale tak nie jest. Początkowo pętliśmy wszystkie wiersze w pliku i przechodziliśmy do następnego wiersza, kiedy już to zrobiliśmy. Tutaj Python ma listę WSZYSTKICH linii: /, wyobraź sobie, że robisz to z plikiem 10GB! Twój kod się zawiesił.
Teraz wróćmy do zakresu() i lista (zakres())
Doing for x in range(0, 6):
pozwala nam przejść do następnego numeru w zakresie i całkowicie zapomnieć o poprzednim (gramatyki śrubki).
jednak robi for x in list(range(0, 6)):
utrzymuje całą listę numerów zapisanych w pamięci i jest taka sama jak robi
numlist = [x for x in range(6)]
for x in numlist:
print(x)
Kiedy trzeba całą listę danych w kodzie, należy użyć metody listy. Ale gdy potrzebujesz tylko jednego kawałka danych na raz (najprostszy przykład, kopiowanie pliku w porcjach), użyj funkcji generatora, aby zaoszczędzić miejsce. Możesz skopiować co 1 milion linii pliku, używając tylko 54 MB (zakładając, że nie masz szalenie długich linii). Jednakże, jeśli mamy mały plik 2kb, możemy po prostu skopiować to bez generatora. To nie jest warte czasu i jest wolniejsze w tym przypadku.
Więc w Pythonie 3 jest "range (x, y)" coś zbliżonego do generatora? Właśnie coś zastanawiałem się odkąd pierwszy raz zobaczyłem to zachowanie ... – Kyrubas
Na razie celowe, ponieważ tłumacz online, którego użyłem do uzyskania przykładu timeit to Python 2.7, więc użyłem xrange zamiast zakresu. Ale nie powinno to mieć znaczenia, ponieważ zasięg Pythona 3 to xrange Pythona 2.x() –
Ok Pomyślałem, że to coś takiego. Chciałem tylko upewnić się, że jest to zamierzone. – Scott