Bir diziyi python ile karıştır, dizi öğesi sırasını python ile rastgele seç


261

Bir diziyi python ile karıştırmanın en kolay yolu nedir?


28
+1, python belgelerinin en yararlı parçalarını her zaman üstün SO Q&A biçimine taşımak için.
charleslparker

1
orijinal diziyi değiştirmeyen ancak yeni bir karıştırılmış dizi döndüren bir seçenek var mı?
Charlie Parker

5
ile yeni bir dizi (değiştirilmemiş) alabilirsiniz new_array = random.sample( array, len(array) ).
Charlie Parker

Yanıtlar:


464
import random
random.shuffle(array)

3
orijinal diziyi değiştirmeyen ancak yeni bir karıştırılmış dizi döndüren bir seçenek var mı?
Charlie Parker

@Charlie Ayrı bir soru sormak iyi bir şey olurdu. (Belki başka biri bunu zaten sordu.)
David Z

13
İronik bir şekilde, bu sayfa Google'da sadece "python shuffle dizisi" ni aradığımda en çok hit oldu
Joshua Huber

2
@Charlie insanları Google'a bu soruları yığın taşması gibi yerlerde cevap bulabilmeleri için Google'a gönderir. Yinelenmediği sürece, yığın taşmasını kaynak olarak bir seçenek haline getirmekle ilgili yanlış bir şey yoktur
Matt

@javadba Bu aslında ilk soruya bir cevaptı. Google'da bazı kazmalarda bulunsa bile yığın taşması hakkında soru sormanın yanlış bir yanı yok. Gelecekteki insanların kendi kazmalarını yaptıkları zaman yığın akışındaki cevabı bulmasını sağlar.
Matt

108
import random
random.shuffle(array)

2
orijinal diziyi değiştirmeyen ancak yeni bir karıştırılmış dizi döndüren bir seçenek var mı?
Charlie Parker

36

Bunu sklearn kullanarak yapmanın alternatif yolu

from sklearn.utils import shuffle
X=[1,2,3]
y = ['one', 'two', 'three']
X, y = shuffle(X, y, random_state=0)
print(X)
print(y)

Çıktı:

[2, 1, 3]
['two', 'one', 'three']

Avantajı: Eşlemeyi bozmadan birden fazla diziyi aynı anda rastgele sıralayabilirsiniz. Ve 'random_state', tekrarlanabilir davranış için karıştırma işlemini kontrol edebilir.


1
Teşekkürler, aynı anda iki diziyi karıştırmak çok faydalıdır.
Dmitry

1
Bunu arıyordum, TNX!
nOp

2
bu, kabul edilen cevaptan daha eksiksizdir (ve genellikle daha yararlıdır)
javadba

21

Diğer cevaplar en kolay olanıdır, ancak random.shuffleyöntemin aslında hiçbir şey döndürmemesi biraz can sıkıcıdır - sadece verilen listeyi sıralar. Çağrıları zincirlemek veya yalnızca bir satırda karıştırılmış bir dizi bildirmek istiyorsanız şunları yapabilirsiniz:

    import random
    def my_shuffle(array):
        random.shuffle(array)
        return array

Sonra aşağıdaki gibi çizgiler yapabilirsiniz:

    for suit in my_shuffle(['hearts', 'spades', 'clubs', 'diamonds']):

7
Belirli bir şey döndürmez , çünkü girdiyi yerinde değiştirerek çalıştığını hatırlatmaya çalışır. (Bu bellek tasarrufu sağlayabilir.) İşleviniz de girdisini yerinde değiştirir.
John Y

2
Sanırım bu tarz bir şey. Şahsen başka bir çiftin alacağı şeye ulaşmak için tek bir satır yazabilmeyi tercih ederim. Programların mümkün olduğunca kısa olmasına izin veren bir dilin, bu durumlarda geçilen nesneyi geri döndürme eğilimi olmadığı garip görünüyor. Girişi yerinde değiştirdiğinden, bu sürüme çağrı yapmak için random.shuffle çağrısını sorunsuz bir şekilde değiştirebilirsiniz.
Mark Rhodes

12
Python aslında mümkün olduğunca kısa olmayı hedeflemiyor. Python, okunabilirliği ifadeyle dengelemeyi amaçlamaktadır. Bu oldukça kısadır, çünkü çok üst düzey bir dildir. Python'un kendi yerleşikleri genellikle (her zaman değil) ya "işlev benzeri" (değer döndürür, ancak yan etkilere sahip değildir) ya da "prosedür benzeri" (yan etkiler yoluyla çalışır ve hiçbir şey döndürmez) olmaya çalışır. Bu, Python'un ifadeler ve ifadeler arasındaki oldukça katı ayrımı ile el ele gider.
John Y

Güzel. Koddaki farkı hemen görmek için my_shuffle olarak yeniden adlandırmanızı öneririm.
Jabba

Belki, ancak bu erken optimizasyon olabilir (yararlı olabilir, ancak karıştırma ihtiyacı açıkça diziyi döndürme ihtiyacını gerektirmez). Ayrıca, shuffle (dizi), shuffle'ın bazı kullanımlarının ardından 3 + n (kez kullanım) yerine sadece 2 satır olurdu, ancak birçok kez kullanırsanız bir tasarruf olacağını tahmin ediyorum. İşte bu tür şeyleri tartışan harika bir video (örneğin fantom gereksinimleri ve erken optimizasyon) - pyvideo.org/video/880/stop-writing-classes
Aaron Newton

12

Normal Python listeleriyle uğraşırken, random.shuffle() , işi önceki cevapların gösterdiği gibi yapar.

Ama ndarray( numpy.array) söz konusu olduğunda random.shuffle, orijinali kırmış gibi görünüyor ndarray. İşte bir örnek:

import random
import numpy as np
import numpy.random

a = np.array([1,2,3,4,5,6])
a.shape = (3,2)
print a
random.shuffle(a) # a will definitely be destroyed
print a

Sadece kullan: np.random.shuffle(a)

Gibi random.shuffle, np.random.shuffleyerinde dizi karıştırır.


2
yok edilenin tam olarak anlamı nedir? (yani, bu bağlamda - ben bir ELL değilim.)
dbliss

A = np.array'ı (aralık (9)) denersem yeniden şekillendirir ([3,3])
Nicholas McCarthy

11

Yeni bir dizi istemeniz durumunda şunları kullanabilirsiniz sample:

import random
new_array = random.sample( array, len(array) )

3

Dizinizi rastgele anahtarla sıralayabilirsiniz

sorted(array, key = lambda x: random.random())

anahtar sadece bir kez okunabilir bu yüzden sıralama sırasında öğeyi karşılaştırmak hala etkili.

ancak random.shuffle(array)C dilinde yazıldığı için daha hızlı görünecek


1
bu, dizinin her öğesi için yeni bir rastgele öğe oluşturur mu?
javadba

@javadba Hayır, bu sadece bir diziyi rastgele dizine göre sıralar, bu da diziyi karıştırır
Trinh Hoang Nhu

1
Maalesef ben belki istemedim temizlemek değildi arrayDemek Randomelemanı: yani içinde veriyor olabilir yeni sınıf örneğine her seferinde. Aslında emin değilim: bunu yapmak için yanlış bir yol olurdu: bir oluşturmak ve sonra çağırmak gerekir . lambdarandom.random()RandomjavaRandom rng = Random()rng.nextGaussian()random.random()
Python'un

1
Kodunuz cevap olarak düzelse de Kodunuzun ne yaptığını incelerken, cevabınızın kalitesini artırabilir. Makaleyi Ödeme: İyi bir yanıtı nasıl yazarım?
LuFFy

1

Önceki yanıtlara ek olarak, başka bir işlev tanıtmak istiyorum.

numpy.random.shuffleyanı sıra random.shuffleyerinde üreticimizin gerçekleştirin. Ancak, karıştırılmış bir dizi döndürmek istiyorsanız numpy.random.permutationkullanılacak işlevdir.


1

Kullandığımı bilmiyorum random.shuffle()ama bana 'Hiçbiri' döndürüyor, bu yüzden bunu yazdım, birine yardımcı olabilir

def shuffle(arr):
    for n in range(len(arr) - 1):
        rnd = random.randint(0, (len(arr) - 1))
        val1 = arr[rnd]
        val2 = arr[rnd - 1]

        arr[rnd - 1] = val1
        arr[rnd] = val2

    return arr

2
evet Hiçbiri döndürmez, ancak dizi değiştirilir, gerçekten bir şey döndürmek istiyorsanız, bu içe aktarma rasgele def shuffle (arr) yapın: random.shuffle (arr) return arr
user781903

0
# arr = numpy array to shuffle

def shuffle(arr):
    a = numpy.arange(len(arr))
    b = numpy.empty(1)
    for i in range(len(arr)):
        sel = numpy.random.random_integers(0, high=len(a)-1, size=1)
        b = numpy.append(b, a[sel])
        a = numpy.delete(a, sel)
    b = b[1:].astype(int)
    return arr[b]

0

Farkında olmak random.shuffle() bu tekrarları neden olduğundan çok boyutlu diziler üzerinde kullanılmamalıdır.

Bir diziyi ilk boyutu boyunca karıştırmak istediğinizi düşünün, aşağıdaki test örneğini oluşturabiliriz,

import numpy as np
x = np.zeros((10, 2, 3))

for i in range(10):
   x[i, ...] = i*np.ones((2,3))

böylece birinci eksen boyunca i-eleman, tüm elemanların i'ye eşit olduğu bir 2x3 matrisine karşılık gelir.

Çok boyutlu diziler için doğru karıştırma işlevini kullanırsak, yani np.random.shuffle(x)dizi ilk eksen boyunca istenildiği gibi karıştırılır. Ancak, kullanmak random.shuffle(x)tekrarlara neden olur. len(np.unique(x))Karıştırmadan sonra koşarak bunu kontrol edebilirsiniz, bu da size 10 (beklendiği gibi) verir np.random.shuffle()ancak kullanırken sadece yaklaşık 5random.shuffle() .

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.