Python 2.X'te range ve xrange fonksiyonları arasındaki fark nedir?


719

Görünüşe göre xrange daha hızlı ama neden daha hızlı (ve anekdot dışında daha hızlı olduğuna dair bir kanıt yok) ya da bunun dışında ne olduğu hakkında hiçbir fikrim yok

for i in range(0, 20):
for i in xrange(0, 20):

Yanıtlar:


817

Python 2.x'te:

  • rangebir liste oluşturur, böylece yaparsanız range(1, 10000000)bellekteki 9999999öğelerle birlikte bir liste oluşturur .

  • xrange tembel olarak değerlendirilen bir dizi nesnesidir.

Python 3'te, rangepython'lara eşdeğerdir xrangeve listeyi almak için kullanmanız gerekir list(range(...)).


65
xrange tam olarak bir jeneratör değildir, ancak tembel olarak değerlendirir ve bir jeneratör gibi davranır.
Vaibhav Mishra

47
xrange(x).__iter__()bir jeneratördür.
augustomen

34
Menzili tembel yapmak yerine neden xrange yaptılar?
Rob Grant

22
@ RobertGrant, yaptılar. Python 3'te. (Python 2.x satırında bunu yapamazlardı, çünkü tüm değişiklikler geriye dönük olarak uyumlu olmalıdır.)
Paul Draper

12
@Ratul, her birinin ibaşlatma yerine talep üzerine değerlendirildiği anlamına gelir .
Onilol

223

aralık bir liste oluşturur, bu nedenle bunu yaparsanız range(1, 10000000)bellekteki 9999999öğeleri içeren bir liste oluşturur .

xrange Bir jeneratör, bu nedenle bir dizi amacı, a, bu değerlendirir lazily.

Bu doğrudur, ancak Python 3'te .range()Python 2 tarafından uygulanacaktır .xrange(). Listeyi gerçekten oluşturmanız gerekiyorsa yapmanız gerekenler:

list(range(1,100))

3
O aralığı gibi halkalar için kullanılacak dizin üretmek için çoğunlukla olduğu gibi (mevcut uygulamalar kırma ile ilgili) büyük bir sorun olma görmek yok "(10, 1) aralığında i için:"
Benjamin AUTIN

10
+1 Bu cevap için teşekkürler, Python 3'ün aralığı xrange ile değiştirmesi hakkında bilgi çok yararlıdır. Aslında birine xrange kullanmasını veya menzili kullanmasını söyledim ve python 3'te önemli olmadığını söylediler, bu yüzden google daha fazla bilgi aradı ve bu cevap geldi :)
Cervo

xrangeJeneratör çağırmanın nesi yanlış ? Bu, yieldifadeyi içeren bir işlevdir ve sözlüğe göre bu işlevlere jeneratör denir.
kış ışığı

@winterlight, bunun için doğru terimin yineleyici olduğunu düşünün. Jeneratörler de alabilmelidir.
McSinyx

112

Unutmayın, timeithangi küçük kod parçacıklarının daha hızlı olduğunu test etmek için modülü kullanın!

$ python -m timeit 'for i in range(1000000):' ' pass'
10 loops, best of 3: 90.5 msec per loop
$ python -m timeit 'for i in xrange(1000000):' ' pass'
10 loops, best of 3: 51.1 msec per loop

Şahsen, her zaman kullanıyorum .range(), gerçekten büyük listelerle uğraşmadıkça - gördüğünüz gibi, bir milyon giriş listesi için, zamana göre, ek yük sadece 0.04 saniyedir. Ve Corey'nin işaret ettiği gibi, Python 3.0'da .xrange()gidecek ve .range()yine de size güzel yineleyici davranışı verecektir.


12
Timeit örneği için +1. . Not: pencerelerde çalıştırmak için o yani" Yani kod olacak çift tırnak kullanmak için gereklidir cmdpython -m timeit "for i in xrange(1000000):" " pass"
sap

10
Xrange'in ana faydası zaman değil, bellektir.
endolith

3
Pratik cevap için +1: büyük olmadıkça aralığı kullanın . BTW kavramsal olarak aynı, doğru mu? İşin garibi hiçbir cevap bunu ortaya koymaz.
Bob Stein

6
Eğer xrange daha hızlıysa ve bellek tutmuyorsa, neden menzili kullanıyorsunuz?
Austin Mohr

8
Genel olarak beyanınıza katılıyorum, ancak değerlendirmeniz yanlış: the extra overhead is only 0.04 secondsona bakmanın doğru yolu değil, (90.5-51.1)/51.1 = 1.771 times slowerdoğru çünkü programınızın çekirdek döngüsü ise potansiyel olarak tıkanabilir. Ancak, bu küçük bir parça ise 1.77x fazla değildir.
chacham15

65

xrangesadece aralık parametrelerini saklar ve talep üzerine sayıları üretir. Ancak Python'un C uygulaması şu anda argümanlarını C uzunlarıyla kısıtlıyor:

xrange(2**32-1, 2**32+1)  # When long is 32 bits, OverflowError: Python int too large to convert to C long
range(2**32-1, 2**32+1)   # OK --> [4294967295L, 4294967296L]

Python 3.0'da sadece rangeve bunun 2.x gibi davrandığını, xrangeancak minimum ve maksimum bitiş noktalarında sınırlama olmadığını unutmayın.


39

xrange bir yineleyici döndürür ve aynı anda yalnızca bir sayıyı bellekte tutar. aralık, tüm sayılar listesini hafızada tutar.


9
xrangeyok değil bir yineleyici döndürür.
abarnert

and only keeps one number in memory at a timeve geri kalanı nereye yerleştirilir lütfen bana yol göster ..
SIslam

5
@SIslam Başlangıç, bitiş ve akımı biliyorsa, bir sonrakini tek tek hesaplayabilir.
Justin Meiners

30

Kütüphane Referansı ile biraz zaman geçirin . Ne kadar aşina olursanız, bunun gibi soruların cevaplarını o kadar hızlı bulabilirsiniz. Yerleşik nesneler ve türler hakkında ilk birkaç bölüm özellikle önemlidir.

Xrange türünün avantajı, bir xrange nesnesinin temsil ettiği aralığın boyutu ne olursa olsun her zaman aynı miktarda bellek almasıdır. Tutarlı performans avantajları yoktur.

Python yapısı hakkında hızlı bilgi bulmanın başka bir yolu da docstring ve yardım fonksiyonudur:

print xrange.__doc__ # def doc(x): print x.__doc__ is super useful
help(xrange)

1
Kütüphane iyidir ama sahip olduğunuz sorunun cevabını almak her zaman kolay değildir.
Teifion

2
Kütüphane referansına gidin, ctrl + f tuşlarına basın, aralığı arayın ve iki sonuç elde edin. Bu sorunun cevabını bulmak çok fazla çaba değil.
David Locke

1
Kitaplık başvurusu çalışmıyor. Lütfen güncelleyebilir misiniz?
mk ..

14

Kimsenin doc okumasından şok oldum :

Bu işlev çok benzer range(), ancak xrangeliste yerine bir nesne döndürür . Bu, hepsi aynı anda depolanmadan karşılık gelen listeyle aynı değerleri veren opak bir dizi türüdür. Avantajı xrange()üzerinde range()minimal (beri xrange()aralığın elemanların tüm bu döngü olması gibi (hiç kullanılmamış zaman çok büyük bir aralık bir bellek-hasret makinede kullanılmış veya durumlar hariç onlar için sorulduğunda hala değerleri oluşturmak için vardır) genellikle ile sonlandırılır break).


13

aralık bir liste oluşturur, bu nedenle aralık (1, 10000000) yaparsanız, 10000000 öğeyle bellekte bir liste oluşturur. xrange bir jeneratördür, bu yüzden tembel olarak değerlendirir.

Bu size iki avantaj sağlar:

  1. Bir daha almadan uzun listeleri tekrarlayabilirsiniz MemoryError.
  2. Her sayıyı tembel bir şekilde çözdüğü için, yinelemeyi erken durdurursanız, tüm listeyi oluşturmak için zaman kaybetmezsiniz.

12

Bu basit örnekte xrangeaşırı avantajı bulacaksınız range:

import timeit

t1 = timeit.default_timer()
a = 0
for i in xrange(1, 100000000):
    pass
t2 = timeit.default_timer()

print "time taken: ", (t2-t1)  # 4.49153590202 seconds

t1 = timeit.default_timer()
a = 0
for i in range(1, 100000000):
    pass
t2 = timeit.default_timer()

print "time taken: ", (t2-t1)  # 7.04547905922 seconds

Yukarıdaki örnek, durumunda daha iyi bir şey yansıtmamaktadır xrange.

Şimdi range, gerçekten yavaş olan aşağıdaki duruma bakın xrange.

import timeit

t1 = timeit.default_timer()
a = 0
for i in xrange(1, 100000000):
    if i == 10000:
        break
t2 = timeit.default_timer()

print "time taken: ", (t2-t1)  # 0.000764846801758 seconds

t1 = timeit.default_timer()
a = 0
for i in range(1, 100000000):
    if i == 10000:
        break
t2 = timeit.default_timer() 

print "time taken: ", (t2-t1)  # 2.78506207466 seconds

İle range, zaten 0 ila 100000000 (zaman alıcı) arasında bir liste oluşturur, ancak xrangebir jeneratördür ve sadece ihtiyaca göre sayılar üretir, yani yineleme devam ederse.

Python-3'te, rangeişlevselliğin uygulanması xrangePython-2'deki ile aynıdır xrange, Python-3'te ise

Mutlu Kodlama !!


11

Optimizasyon nedenleriyle.

range (), baştan sona bir değerler listesi oluşturur (örneğinizde 0 .. 20). Bu, çok geniş aralıklarda pahalı bir operasyon haline gelecektir.

xrange () ise çok daha optimize edilmiştir. bir sonraki değeri yalnızca gerektiğinde (bir xrange dizi nesnesi aracılığıyla) hesaplar ve range () gibi tüm değerlerin bir listesini oluşturmaz.


9

range(x,y)bir fordöngü kullanırsanız x ile y arasındaki her sayının bir listesini döndürür , o rangezaman yavaştır. Aslında, rangedaha geniş bir Endeks aralığına sahiptir. range(x.y)x ve y arasındaki tüm sayıların bir listesini yazdırır

xrange(x,y)döner, xrange(x,y)ancak bir fordöngü kullandıysanız , o zaman xrangedaha hızlıdır. xrangedaha küçük bir Dizin aralığına sahiptir. xrangeyalnızca çıktı almakla xrange(x,y)kalmaz, aynı zamanda içindeki tüm sayıları saklar.

[In] range(1,10)
[Out] [1, 2, 3, 4, 5, 6, 7, 8, 9]
[In] xrange(1,10)
[Out] xrange(1,10)

Bir fordöngü kullanırsanız , o zaman işe yarar

[In] for i in range(1,10):
        print i
[Out] 1
      2
      3
      4
      5
      6
      7
      8
      9
[In] for i in xrange(1,10):
         print i
[Out] 1
      2
      3
      4
      5
      6
      7
      8
      9

Döngüleri kullanırken çok fazla bir fark yoktur, ancak sadece yazdırırken bir fark vardır!


8

range (): range (1, 10), 1'den 10'a kadar bir sayı döndürür ve tüm listeyi bellekte tutar.

xrange (): range () gibi, ancak bir liste döndürmek yerine, isteğe bağlı aralıktaki sayıları üreten bir nesne döndürür. Döngü için bu, range () 'den biraz daha hızlı ve bellekte daha verimlidir. xrange () nesnesini yineleyici gibi kullanır ve talep üzerine sayıları oluşturur.

In [1]: range(1,10)

Out[1]: [1, 2, 3, 4, 5, 6, 7, 8, 9]

In [2]: xrange(10)

Out[2]: xrange(10)

In [3]: print xrange.__doc__

xrange([start,] stop[, step]) -> xrange object

6

Diğer cevapların bazıları Python 3 2.x 's ortadan söz rangeve 2.x' s adını xrangekadar range. Ancak, 3.0 veya 3.1 (hiç kimsenin olmaması gereken) kullanmıyorsanız, aslında biraz farklı bir tür.

As 3.1 dokümanlar ki:

Aralık nesnelerinin çok az davranışı vardır: yalnızca dizin oluşturma, yineleme ve lenişlevi destekler.

Bununla birlikte, 3.2+, rangetam bir dizidir - genişletilmiş dilimleri ve a collections.abc.Sequenceile aynı semantiğe sahip tüm yöntemleri destekler list. *

Ve en azından CPython ve PyPy'de (şu anda var olan sadece iki 3.2+ uygulama), indexve countyöntemleri ve inoperatörünün sabit zamanlı uygulamaları da vardır (yalnızca tamsayıları geçtiğiniz sürece). Bu, yazmanın 123456 in r3.2+'de makul olduğu anlamına gelirken, 2.7 veya 3.1'de korkunç bir fikir olurdu.


* 2.6-2.7 ve 3.0-3.1'de issubclass(xrange, collections.Sequence)geri Truedönmesi, 3.2'de düzeltilen ve desteklenmeyen bir hatadır .


6

Python 2.x içinde

range (x) , bellekte x öğesiyle oluşturulan bir liste döndürür.

>>> a = range(5)
>>> a
[0, 1, 2, 3, 4]

xrange (x) , istek üzerine sayıları üreten bir üretici nesnesi olan bir xrange nesnesi döndürür. for-loop sırasında hesaplanırlar (Tembel Değerlendirme).

Döngü için bu, range () 'den biraz daha hızlı ve bellekte daha verimlidir.

>>> b = xrange(5)
>>> b
xrange(5)

xrange()bir jeneratör değil. xrange(n).__ iter __ () `dir.
th3an0maly

5

(I kullanmalıyım biliyorum bir döngü içinde xrange karşı aralığı test edilirken sürümüyle gelen timeit ama bu hızla basit bir liste anlama örneği kullanılarak bellekten kadar hacklendi) Aşağıdaki bulundu:

import time

for x in range(1, 10):

    t = time.time()
    [v*10 for v in range(1, 10000)]
    print "range:  %.4f" % ((time.time()-t)*100)

    t = time.time()
    [v*10 for v in xrange(1, 10000)]
    print "xrange: %.4f" % ((time.time()-t)*100)

hangi verir:

$python range_tests.py
range:  0.4273
xrange: 0.3733
range:  0.3881
xrange: 0.3507
range:  0.3712
xrange: 0.3565
range:  0.4031
xrange: 0.3558
range:  0.3714
xrange: 0.3520
range:  0.3834
xrange: 0.3546
range:  0.3717
xrange: 0.3511
range:  0.3745
xrange: 0.3523
range:  0.3858
xrange: 0.3997 <- garbage collection?

Veya for döngüsünde xrange kullanarak:

range:  0.4172
xrange: 0.3701
range:  0.3840
xrange: 0.3547
range:  0.3830
xrange: 0.3862 <- garbage collection?
range:  0.4019
xrange: 0.3532
range:  0.3738
xrange: 0.3726
range:  0.3762
xrange: 0.3533
range:  0.3710
xrange: 0.3509
range:  0.3738
xrange: 0.3512
range:  0.3703
xrange: 0.3509

Snippet'im düzgün bir şekilde test ediliyor mu? Yavaş xrange örneği hakkında yorumlarınız var mı? Veya daha iyi bir örnek :-)


2
Bir kerede böyle bir kıyaslama yapmak kesin zamanlama sonuçları sağlamaz. Her zaman bir fark vardır .. GC veya CPU'yu çalan başka bir süreç olabilir ... herhangi bir şey. Bu yüzden kriterler genellikle 10-100-1000 -... çalışır
Vajk Hermecz

Bu sadece aceleci bir snippet çıktısı - birkaç kez koştum, ancak sadece 100'e xrangekadar ve Python 3 ile karşılaştırma artık gereksiz olsa da, biraz daha hızlı görünüyordu.
Dave Everitt

3
Bunun timeitiçin bu. Birçok kez koşmak, GC'yi devre dışı bırakmak, yerine en iyi saati kullanmak timevb.
İle ilgilenir

4

python'daki xrange () ve range (), kullanıcıya benzer şekilde çalışır, ancak fark, her iki işlevi kullanarak belleğin nasıl tahsis edildiği hakkında konuştuğumuzda ortaya çıkar.

Range () yöntemini kullanırken, oluşturduğu tüm değişkenler için bellek ayırırız, bu nedenle daha büyük no ile kullanılması önerilmez. oluşturulacak değişkenler.

xrange () ise bir seferde sadece belirli bir değer üretir ve sadece for döngüsüyle birlikte gerekli tüm değerleri yazdırmak için kullanılabilir.


3

range tüm listeyi oluşturur ve listeyi döndürür. xrange yapmaz - istek üzerine listedeki sayıları üretir.


2

xrange bir yineleyici kullanır (anında değerler üretir), aralık bir liste döndürür.


2

Ne?
rangeçalışma zamanında statik bir liste döndürür. değerlerin gerektiğinde ve gerektiğinde üretildiği bir (kesinlikle bir tane olmasa da bir jeneratör gibi davranır)
xrangedöndürür object.

Hangisi ne zaman kullanılır?

  • kullanım xrangeÖzellikle bir cep telefonu gibi "belleğe duyarlı bir sisteminiz" olduğunda, 1 milyar gibi devasa bir aralık için bir liste oluşturmak istiyorsanız .
  • rangeListeyi birkaç kez tekrarlamak istiyorsanız kullanın .

PS: Python 3.x rangeişlevi == Python 2.x xrangeişlevi.


xrangebir jeneratör nesnesini döndürmez.
abarnert

Doğru anlarsam
kmario23

O zaman wiki yanlış. (Bu yorumu ekleyen ve imzalayan "SH" nin kim olduğunu bilmiyorum.) Resmi belgeler doğrudur; kendiniz test edebilir ve bunun bir jeneratör veya sıra olup olmadığını görebilirsiniz.
abarnert

tamam. Ancak bunu okuduktan sonra hala kafa karıştırıcı: stackoverflow.com/questions/135041/…
kmario23

1
Eğlenceli soru, tercüman resmi belgelerle veya farklı bir tercümanla aynı fikirde olmadığında ne yapılacağıdır ... Ama neyse ki, bu çok sık ortaya
çıkmıyor

2

Herkes çok iyi açıkladı. Ama kendim görmesini istedim. Python3 kullanıyorum. Bu nedenle, kaynak izleyicisini açtım (Windows'ta!) Ve önce ilk olarak aşağıdaki komutu yürüttüm:

a=0
for i in range(1,100000):
    a=a+i

ve sonra 'Kullanımda' bellekteki değişikliği kontrol etti. Önemsizdi. Sonra, aşağıdaki kodu koştu:

for i in list(range(1,100000)):
    a=a+i

Anında kullanım için hafızanın büyük bir kısmını aldı. Ve ikna olmuştum. Kendiniz deneyebilirsiniz.

Python 2X kullanıyorsanız, 'range ()' öğesini ilk kodda 'xrange ()' ve 'list (range ())' yerine 'range ()' ile değiştirin.


2

Yardım belgelerinden.

Python 2.7.12

>>> print range.__doc__
range(stop) -> list of integers
range(start, stop[, step]) -> list of integers

Return a list containing an arithmetic progression of integers.
range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0.
When step is given, it specifies the increment (or decrement).
For example, range(4) returns [0, 1, 2, 3].  The end point is omitted!
These are exactly the valid indices for a list of 4 elements.

>>> print xrange.__doc__
xrange(stop) -> xrange object
xrange(start, stop[, step]) -> xrange object

Like range(), but instead of returning a list, returns an object that
generates the numbers in the range on demand.  For looping, this is 
slightly faster than range() and more memory efficient.

Python 3.5.2

>>> print(range.__doc__)
range(stop) -> range object
range(start, stop[, step]) -> range object

Return an object that produces a sequence of integers from start (inclusive)
to stop (exclusive) by step.  range(i, j) produces i, i+1, i+2, ..., j-1.
start defaults to 0, and stop is omitted!  range(4) produces 0, 1, 2, 3.
These are exactly the valid indices for a list of 4 elements.
When step is given, it specifies the increment (or decrement).

>>> print(xrange.__doc__)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'xrange' is not defined

Fark açıktır. Python 2.x içinde, rangebir liste xrangedöndürür, yinelenebilir bir xrange nesnesi döndürür.

Python 3.x içinde Python 2.x rangeolur xrangeve xrangekaldırılır.


1

0-N öğelerin taranması / yazdırılması için, aralık ve xrange aşağıdaki gibi çalışır.

range () - bellekte yeni bir liste oluşturur ve tüm 0 ila N öğelerini (tamamen N + 1) alır ve yazdırır. xrange () - öğeleri tarayan ve yalnızca o anda karşılaşılan öğeyi belleğe tutan bir yineleyici örneği oluşturur, bu nedenle her zaman aynı miktarda bellek kullanır.

Gerekli öğenin sadece listenin başında olması durumunda çok fazla zaman ve bellek tasarrufu sağlar.


1
xrangeyineleyici örneği oluşturmaz. xrangeYinelenebilir, ancak yineleyici olmayan bir nesne yaratır - bir liste gibi neredeyse (ancak tam olarak değil) bir dizi.
abarnert

1

Kapsama bir döner listesi ise xrange bir döner xrange , aralık boyutu ne olursa olsun, bu durumda olduğu gibi, tek bir öğe olarak oluşturulur ve aralığı kullanılması durumunda ise yineleme başına kullanılabilir, aynı bellek alır nesne, tüm elemanlar bir kez ve en oluşturulacak bellekte kullanılabilir.


1

Daha küçük argümanlar için range(..)/ xrange(..):

$ python -m timeit "for i in xrange(10111):" " for k in range(100):" "  pass"
10 loops, best of 3: 59.4 msec per loop

$ python -m timeit "for i in xrange(10111):" " for k in xrange(100):" "  pass"
10 loops, best of 3: 46.9 msec per loop

Bu durumda xrange(100)sadece% 20 daha verimlidir.


1

range: -range, her şeyi aynı anda dolduracaktır.

xrange: -xrange, jeneratör gibi bir şeydir, sayı aralığını istediğinizde resme gelecektir, ancak loop.so için bellek kullanmak istediğinizde olduğu gibi saklanmasını istemezsiniz.


1

Ayrıca, eğer do list(xrange(...))değerine eşdeğer olacaksa range(...).

Yani listyavaş.

Ayrıca xrangediziyi gerçekten tamamlamıyor

Bu yüzden bu bir liste değil, bir xrangenesne


1

range() Python'da 2.x

Bu işlev aslında range()Python'da bulunan eski bir işlevdir 2.xve birlist ve belirtilen aralıktaki öğeleri içeren nesnenin .

Ancak, bir dizi sayı içeren bir listeyi başlatmak söz konusu olduğunda bu uygulama çok verimsizdir. Örneğin, for i in range(1000000)bu listenin belleğe kaydedilmesini gerektirdiğinden, hem bellek hem de zaman kullanımı açısından yürütülmesi çok pahalı bir komut olacaktır.


range()Python 3.xve xrange()Python'da2.x

Python 3.xdaha yeni bir uygulamasına başladık range()yeni uygulama Python zaten mevcut iken ( 2.xaracılığıylaxrange() işlev ).

range()Olarak bir stratejiyi kullanan yavaş değerlendirme. Aralıktaki öğelerin büyük bir listesini oluşturmak yerine, yeni uygulama sınıfı range, belirli bir aralıkta gerekli öğeleri temsil eden hafif bir nesne olan sınıfı açık bir şekilde bellekte saklamadan sunar (bu, jeneratörler gibi gelebilir, ancak tembel değerlendirme kavramı farklı).


Örnek olarak aşağıdakileri göz önünde bulundurun:

# Python 2.x
>>> a = range(10)
>>> type(a)
<type 'list'>
>>> b = xrange(10)
>>> type(b)
<type 'xrange'>

ve

# Python 3.x
>>> a = range(10)
>>> type(a)
<class 'range'>

-2

Bu gönderiye bakın aralığı ve xrange arasındaki farkı bulmak için:

Alıntılamak:

rangetam olarak düşündüğünüzü döndürür: 0 ile başlayan tanımlanmış bir uzunluktaki ardışık tamsayıların bir listesi xrange, ancak, bir yineleyici gibi büyük ölçüde hareket eden bir "xrange nesnesi" döndürür


2
Bunun 5 yaşında olduğunun farkındayım, ancak bu yazı neredeyse her şey hakkında yanlış. xrangebir yineleyici değildir. Tarafından döndürülen liste rangeyinelemeyi destekliyor (bir liste hemen hemen yinelenebilir bir prototip örneğidir). Toplam faydası xrange"minimal" değildir. Ve bunun gibi.
abarnert
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.