2016-03-15 18 views
7

Bazı numaraları sıralamak için python kullanıyorum. Bir değer (4, 8, 16, 32, 64, vb.) Girmeme, sayı dizisi oluşturmamıza ve sıralarını yeniden düzenlememize olanak tanıyan bir işlev oluşturmak istiyorum.Döngüler için dinamik bir sayı ile yineleyin (Python)

I değeri = 4 sırası belirleme ayrıntılı rakamlar ve değer = 4 dizisi için 8.

(x = [0, 1, 2, 3]) bölünmüş olmalıdır ekledik iki ([0,1] ve [2,3]) cinsinden ve daha sonra her bir dizideki ilk sayıya göre birleştirilmiştir ([0, 2, 1, 3]). değer için

Figure with sequence for value = 4

= 8 dizisi (x = [0, 1, 2, 3, 4, 5, 6, 7]) içine bölünmüş olmalıdır iki ([0, 1, 2, 3 ] ve [4, 5, 6, 7]). Her iki dizinin tekrar ikiye ayrılması gerekir ([0, 1, 2, 3] [0,1] ve [2,3] ve [4, 5, 6, 7] 'ye [4,5] ve [6, 7]). Ardından diziler, her dizideki ilk sayıya ve dizilerden oluşan ikinci diziye göre birleştirilmelidir ([0, 4, 2, 6, 1, 5, 3, 7]).

Figure for sequence for value = 8

I (dinamik döngüler için iç içe) Özyinelemeyi nasıl işleneceğini bilmiyorum. Diziyi bölerek oluşturulan her bir brach ile döngülemeye çalışıyorum. Itertools ve özyinelemeye baktım (Function with varying number of For Loops (python)), ama işe yaramazdım. Aşağıda, şimdiye kadarki yaklaşımımı göstermek için kod ekledim.

Herhangi bir yardım çok takdir edilmektedir. Sıralamayı belirlemek için başka fikirlere de açığım.

Python 2.7.6 ve numpy kullanıyorum.

Kodu:

import numpy 
value = 4 
a = [] 
x = numpy.arange(value) 
y = numpy.array_split(x, 2) 
for i in range(2): 
    for j in y: 
     a.append(j.tolist()[i]) 
print(a) 

Çıktı:

[0, 2, 1, 3] 

Kodu:

import numpy 
value = 8 
a = [] 
x = numpy.arange(value) 
y = numpy.array_split(x, 2) 
for i in range(2): 
    for h in range(2): 
     for j in y: 
     z = numpy.array_split(j, 2) 
       a.append(z[h][i]) 
    print(a) 

Çıktı:

[0, 4, 2, 6, 1, 5, 3, 7] 

Değer = 16 için çıkış [0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7 15] olmalıdır.

+0

ihtiyacınız mı uyuşmuş bir çözüm? Bu basit bir pythonda yapılabilir, sanırım –

+0

Bence ihtiyacın olan şey, sayıların ikili formunu almak ve onları antialphabetically olarak sıralamak. – Ilja

cevap

2

İşte np.transpose ve reshaping kullanarak NumPythonic yoldur -

def seq_pow2(N): 
    shp = 2*np.ones(np.log2(N),dtype=int) 
    return np.arange(N).reshape(shp).transpose(np.arange(len(shp))[::-1]).ravel() 

.T için basitleştirmek olacağını .transpose(np.arange(len(shp))[::-1] unutmayın, bu yüzden basitleştirilmiş bir sürümünü olurdu -

def seq_pow2(N): 
    shp = 2*np.ones(np.log2(N),dtype=int) 
    return np.arange(N).reshape(shp).T.ravel() 

Sen daha da kolaylaştırabilirsiniz ve değiştirme ravel/flattening ürününü fortranile sütun sıralı bir sırayla gerçekleştirerek

def seq_pow2(N): 
    shp = 2*np.ones(np.log2(N),dtype=int) 
    return np.arange(N).reshape(shp).ravel('F') 

Numune ishal - -nihayet bize yol için bu Numpy bazı dizi isleme yapmak ama döngüler için değil kullanımına yapmanın

In [43]: seq_pow2(4) 
Out[43]: array([0, 2, 1, 3]) 

In [44]: seq_pow2(8) 
Out[44]: array([0, 4, 2, 6, 1, 5, 3, 7]) 

In [45]: seq_pow2(16) 
Out[45]: array([ 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15]) 
1

kolay yolu.

N = 8 
pow2 = np.log2(N) 
out = np.arange(N).reshape([2]*pow2).transpose(np.arange(pow2)[::-1]).flatten() 

    array([0, 4, 2, 6, 1, 5, 3, 7]) 

Bu ne bu nx uzunluğuna karşı gelen 2 gücü bir n boyutlu diziye x yeniden şekillendirir olup. Bu yeniden şekillendirildikten sonra, her bir boyutun uzunluğu 2'dir. Sonra tüm boyutları tersine çeviririz ve istediğiniz diziyi elde etmek için düzleştiririz.

Düzenleme

Bu Divakar's Solution benzer bir yaklaşımdır ve o çok daha kısaca tekrar yaptık, ama sadece kuşaklar için buraya bırakacağız.

2

netlik için piton özyinelemeli versiyonu:

def rec(n): 
    if n==1 : return [0] 
    l=[0]*n 
    l[::2]=rec(n//2) 
    for i in range (0,n,2) : l[i+1]=l[i]+n//2 
    return l 

sonucun ikili gösterimini gözlemleyerek,

In [6]: rec(16) 
Out[6]: [0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15] 

için Veya, bir numpy çözüm:

def rearange(N): 
    u=2**arange(N.bit_length()-1) 
    v=arange(N) 
    bits= u[None,:] & v[:,None] 
    return sum(bits*u[::-1],1) 
İlgili konular