2016-04-13 22 views
2

Ben Euler Q gerekli değildir 31.Python Liste değerleri

proje Euler soru için çalışan Burada bu basit bir kod var/mutasyona uğramış değiştirilen; Sadece bilmek istiyorum, neden benim değerlerim mutasyona uğruyor, yani bu [2,0,2,0,2,0,2,0,2,0] 'daki birçok listenin bir listesini yazdırıyor.

coins = [0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1.0, 2.0] 


perms = [] 
def check(c): 
    if sum(c) == 2: 
     print c, "lol", sum(c) 
     perms.append(c) 
    return perms 

c = [0] * 5 
for c[0] in coins: 
    for c[1] in coins: 
     for c[2] in coins: 
      for c[3] in coins: 
       for c[4] in coins: 
        check(c) 

print perms 

Bu nedense çalışmıyor ve çıktı Bununla

[[2.0, 2.0, 2.0, 2.0, 2.0], [2.0, 2.0, 2.0, 2.0, 2.0]...] 

perms = [] 
for c1 in coins: 
    for c2 in coins: 
     for c3 in coins: 
      for c4 in coins: 
       for c5 in coins: 
        if c1+c2+c3+c4+c5 == 2: 
         print c1,c2,c3,c4,c5 
         perms.append([c1,c2,c3,c4,c5]) 


print perms 

olduğunu bu işleri ve çıkış iki arasındaki fark nedir

[[0.1, 0.2, 0.2, 0.5, 1.0], [0.1, 0.2, 0.2, 1.0, 0.5], [0.1, 0.2, 0.5, 0.2, 1.0],[0.1, 0.2, 0.5, 1.0, 0.2], [0.1, 0.2, 1.0, 0.2, 0.5], [0.1, 0.2, 1.0, 0.5, 0.2],[0.1, 0.5, 0.2, 0.2, 1.0], [0.1, 0.5, 0.2, 1.0, 0.2]...] 

olduğunu ?

Ayrıca, kodumu nasıl kısaltabilirim, belki de yineleme işlevi? Yani paralar içinde c1, sikke ve benzeri c2 yapmak yerine, aynı işi yapmak için sadece bir veya iki döngüye sahibim.

+1

* "belki bir özyineleme işlevi?" * Evet, burada daha iyi olurdu. – jDo

cevap

1

Sorun hala c o perms eklendi sonra olarak alır olmasıdır. Bunun yerine bir kopyasını check geçirebilirsiniz, o zaman işe yarayacak gibi görünüyor.

c = [0] * 5 
for c[0] in coins: 
    for c[1] in coins: 
     for c[2] in coins: 
      for c[3] in coins: 
       for c[4] in coins: 
        check(c[:]) # c[:] creates a copy of c 

BTW, ben bile sen itertools özellikle product, permutations, combinations ve combinations_with_replacement bir göz atmak isteyebilirsiniz ... for c[1] in coins geçerli Python sözdizimi Ayrıca

bilmiyordum.


bir özyinelemeli işlevi aşağıdaki gibi kabaca görünebilir:

def comb(current, target): 
    if sum(current) == target: 
     yield current 
    elif sum(current) < target: 
     for coin in coins: 
      for solution in comb(current + [coin], target): 
       yield solution 

Ancak bu da her parayı kombinasyonları almak için çok yavaş gibi görünüyor.

+0

Teşekkürler. Ve aynı sorunu çözmek için özyinelemeyi nasıl uygulayacağınıza dair herhangi bir fikir var mı? Tekrarlayan tbh .. – SinByCos

+0

Gah, jeneratörler + özyineleme beni gerçekten deliriyor D: Umarım yakında bunu anlayacağım, ama teşekkürler! – SinByCos

1

@tobias_k Eğer itertools den permutations ile bu durumda combinations_with_replacement kullanabileceği, gösterir:

coins = [0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1.0, 2.0] 
perms = set() # invariant no repeated elements, 

# return elements with length=5 repeat 
combinations = combinations_with_replacement(coins,5) 

for comb in combinations: 
    for c1,c2,c3,c4,c5 in permutations(comb): 
     if sum([c1,c2,c3,c4,c5]) == 2: 
      perms.add((c1,c2,c3,c4,c5)) 

NOT: Bu durumda bir liste kullanıyorsanız tekrarlanan veya başka bir şekilde kontrol giderilmelidir.