Python List ve Array - ne zaman kullanılır?


374

Bir 1d dizisi oluşturuyorsanız, bunu Liste olarak uygulayabilir veya standart kütüphanede 'dizi' modülünü kullanabilirsiniz. Her zaman 1d diziler için Listeler kullandım.

Bunun yerine dizi modülünü kullanmak istediğim neden veya durum nedir?

Performans ve bellek optimizasyonu için mi yoksa açık bir şey mi kaçırıyorum?

Yanıtlar:


438

Temel olarak, Python listeleri çok esnektir ve tamamen heterojen, keyfi veriler tutabilir ve amortize edilmiş sabit zamanda çok verimli bir şekilde eklenebilir . Listenizi zamanla verimli ve sorunsuz bir şekilde küçültmeniz ve büyütmeniz gerekiyorsa, bunlar da gidilecek yoldur. Ancak C dizilerinden çok daha fazla alan kullanıyorlar .

array.arrayTürü, diğer taraftan, Cı dizileri üzerinde sadece ince bir sarıcı. Yalnızca aynı türden olan homojen verileri tutabilir ve bu nedenle yalnızca sizeof(one object) * lengthbayt bellek kullanır . Çoğunlukla, bir C dizisini bir uzantıya veya sistem çağrısına (örneğin ioctlveya fctnl) maruz bırakmanız gerektiğinde kullanmalısınız .

array.arrayPython 2.x ( ) içinde değiştirilebilir bir dizeyi temsil etmenin de makul bir yoludur array('B', bytes). Ancak, Python 2.6+ ve 3.x gibi değişken bir bayt dizesi sunar bytearray.

Ancak, homojen bir sayısal veri dizisi üzerinde matematik yapmak istiyorsanız , karmaşık çok boyutlu dizilerdeki işlemleri otomatik olarak vektörleştirebilen NumPy'yi kullanmaktan çok daha iyidir.

Uzun bir hikaye kısaltmak için : matematik yapmaktan başkaarray.array nedenlerle homojen bir C veri dizisine ihtiyacınız olduğunda kullanışlıdır .


9
Numpy.ndarray, array.array ile aynı bellek alanına mı sahip?
Gordon Bean

6
@ Gordon, büyük, bitişik bir dizi durumunda çok benzer olmalıdır: her ikisi de sizeof(element)× (öğe sayısı) bayt ve ek yük için küçük bir sabit başlık gerektirir. Bununla birlikte, ndarray, bitişik olmayan ve seyrek dizilerle başa çıkmak için bazı gelişmiş seçeneklere sahiptir ve bence büyük diziler için bellek ayırmak için bazı takılabilir stratejiler ... Bu gelişmiş özelliklerden bazıları kullanıcıyı daha az bellek haline getirirken, diğerleri daha hafıza.
Dan Lenski

Ayrıca, mikro denetleyicileri mikropython ile programlarken bellek bir sorun olduğunda da yararlıdır
janscas

Bir dizinin i 'elemanı sabit bir zamanda aranabilirken, bağlantılı listede en kötü durumda' n 'sırasını alır. Python listesindeki i'th öğesinin arama süresi nedir?
Nithish Inpursuit Ofhappiness

7
@NithishInpursuitOfhappiness, bir Python listesi bağlantılı bir liste değildir. Dahili olarak bir dizi olarak temsil edilir ve Java ArrayList ile aynı zaman karmaşıklığı özelliklerine sahiptir. Bu nedenle, bir Python listesinin i'th elemanını almak ve ayarlamak sabit bir zaman alır . Python listesine bir öğe eklemek, amortismana tabi sabit bir zaman alır, çünkü dizi boyutu boş kaldığında iki katına çıkar. Bir Python listesinin ortasına öğe eklemek veya listeden çıkarmak, öğelerin değiştirilmesi gerektiğinden O (n) zaman alır . Referans için bakınız: wiki.python.org/moin/TimeComplexity
geofflee

66

Hemen hemen tüm durumlar için normal liste doğru seçimdir. Diziler modülü, C dizileri üzerinde, güçlü bir şekilde yazılmış kaplar ( belgelere bakın ) veren, yapının bir parçası olmayan imzalı / imzasız kısa veya çift gibi daha fazla C benzeri türe erişim sağlayan ince bir sargıya benzer. türleri. Diziler modülünü sadece gerçekten ihtiyacınız varsa kullanın, diğer durumlarda listelerle sopa.


3
Mümkün, asla gerçekten kullanmadı, ancak bazı mikro kriterleri çalıştırmak ilginç olurdu.
André

13
Aslında, hızlı bir test yaptım - 100M girişleri olan bir listeyi ve ilgili diziyle aynı testi topladım ve liste aslında yaklaşık% 10 daha hızlıydı.
Moe

38
Listeler daha hızlıdır, çünkü "raw" veri dizisindeki işlemlerin diziden okurken veya diziye yazarken sürekli olarak python nesneleri oluşturması ve yok etmesi gerekir.
tzot

7
@Moe, yukarıdaki cevabımda belirttiğim gibi, Python'un yerleşik arrayolduğu matematik yapmak için değil . NumPy'yi ndarray10 ^ 8 numaralık bir dizi toplamak için denerseniz, tamamen patlar list. @tzot, yerleşik olanın arraymatematik için neden yavaş olduğu konusunda doğru fikre sahiptir .
Dan Lenski

2
Az önce test ettim, numpy makinemde 86.6x daha hızlı.
Mark

53

Dizi modülü, neden kullanacağınızı bilmiyorsanız muhtemelen ihtiyaç duymadığınız şeylerden biridir (ve bunu küçümseyen bir şekilde söylemeye çalışmama dikkat edin!) . Çoğu zaman, dizi modülü C kodu ile arayüz oluşturmak için kullanılır. Performansla ilgili sorunuza daha doğrudan bir cevap vermek için:

Diziler, bazı kullanımlar için listelerden daha verimlidir. BİLMEYEN bir dizi ayırmanız gerekiyorsa, diziler daha hızlı olabilir ve daha az bellek kullanabilir. GvR'nin bir optimizasyon fıkrası var dizi modülünün kazanan (uzun okunur, ancak buna değer).

Öte yandan, listelerin dizilerden daha fazla bellek tüketmesinin nedenlerinden biri, ayrılmış tüm öğeler kullanıldığında python'un fazladan birkaç öğe ayırmasıdır. Bu, öğelerin listelere eklenmesinin daha hızlı olduğu anlamına gelir. Öyleyse, öğe eklemeyi planlıyorsanız, liste bir yoldur.

TL; DR Bir diziyi yalnızca olağanüstü bir optimizasyon gereksiniminiz varsa veya C kodu ile arabirim kurmanız gerekiyorsa (ve pyrex kullanamazsınız ) kullanırım .


1
Somut örnek için +1 ve hız avantajından bahsediliyor. En iyi cevap bana "Zaman hafızasında bir takas var mı?" ve "Bunun çok ezoterik düşük bellek durumu olmayan bir kullanımı var mı?"
leewz

@leewz tam olarak, bu cevap olarak düşünülmelidir.
Gauri Shankar Badola

21

Bu bir takas!

her birinin artıları:

liste

  • esnek
  • heterojen olabilir

dizi (ör: numpy dizi)

  • birörnek değerler dizisi
  • homojen
  • kompakt (boyut olarak)
  • verimli (işlevsellik ve hız)
  • uygun

2
soru python'daki dizi modülüne başvuruyor; numpy dizileri değil. Boyut verimliliği dışında çok fazla profesyonelleri yok. Daha hızlı değiller.
NONONONONO

14

Anladığım kadarıyla, diziler daha verimli bir şekilde saklanır (yani, Python nesnelerine işaret edenlere karşı bitişik bellek blokları olarak), ancak herhangi bir performans avantajının farkında değilim. Ayrıca, dizilerle aynı tür temel öğeleri saklamanız gerekirken, listeler her şeyi saklayabilir.


8

Standart kütüphane dizileri, ikili listenin, örneğin bir dalga dosyasına yazmak için bir dize listesine bir dize listesine çevrilmesi gibi ikili G / Ç için kullanışlıdır. Bununla birlikte, birçok kişinin belirttiği gibi, herhangi bir gerçek iş yapacaksanız NumPy kullanmayı düşünmelisiniz.


6

Dizileri kullanacaksanız, dizilere çok daha fazla esneklik sağlayan numpy veya scipy paketlerini düşünün.


5

Dizi yalnızca belirli türler için kullanılabilirken, listeler herhangi bir nesne için kullanılabilir.

Diziler ayrıca yalnızca bir türdeki verileri içerebilirken, bir listede çeşitli nesne türlerinin girişleri olabilir.

Diziler, bazı sayısal hesaplamalarda da daha verimlidir.


4
Yerleşik python dizileri performans açısından verimli değildir, yalnızca bellek açısından verimlidir.
tzot

Dizilerin işleme açısından daha verimli olduğu ARE örnekleri vardır. Aşağıdaki yazıma bakın: stackoverflow.com/questions/176011/…
Jason Baker

0

Numpy dizisi ve liste arasındaki önemli bir fark, dizi dilimlerinin orijinal dizideki görünümler olmasıdır. Bu, verilerin kopyalanmadığı ve görünümde yapılan değişikliklerin kaynak diziye yansıtılacağı anlamına gelir.


0

Bu cevap, Liste ve Dizinin ne zaman kullanılacağıyla ilgili neredeyse tüm soruları toplayacaktır:

  1. Bu iki veri türü arasındaki temel fark, bunlar üzerinde gerçekleştirebileceğiniz işlemlerdir. Örneğin, bir diziyi 3'e bölebilirsiniz ve dizinin her öğesini 3'e böler. Aynı şey liste ile yapılamaz.

  2. Liste, python'un sözdiziminin bir parçasıdır, bu yüzden bildirilmesi gerekmez, diziyi kullanmadan önce bildirmeniz gerekir.

  3. Farklı veri türlerinin değerlerini bir listede (heterojen) saklayabilirken, Array'da yalnızca aynı veri türündeki (homojen) değerleri depolayabilirsiniz.

  4. Diziler işlevsellik bakımından zengindir ve hızlıdır, aritmetik işlemler ve listeye kıyasla büyük miktarda veri depolamak için yaygın olarak kullanılır.

  5. Diziler listelere göre daha az bellek alır.

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.