Paraméterátadás

A python nyelv esetében nem célszerű az érték szerinti, illetve cím szerinti paraméterátadás fogalmával dolgozni – érdemes viszont felidézni a mutabilitásról, illetve az immutabilitasról olvasottakat. A listák mutabilisak, a számok immutabilisak: ennek megfelelően változik meg (a függvényen kívül is) a lista tartalma, ugyancsak ennek megfelelően nem változik az i szám értéke.

Tömör összefoglalás olvasható a fentiekről a stackoverflow.com oldalon: How do I pass a variable by reference? Ahogyan az egyik hozzászóló egy hosszabb cikk rövid részletének címére utalva írja, a python nyelv esetén változók helyett nevekre, hivatkozások helyett objektumokra érdemes gondolni: Other languages have “variables”, Python has “names”.

A nyelv dokumentációja részletesen ír az objektumok mutabilitásáról, illetve immutabilitásáról: Data model; valamint a kimeneti paramétert használó függvényekről: How do I write a function with output parameters (call by reference)?

Ezek után az egyik lehetséges megoldás az lehet, hogy a nyelv sajátos vonását, a listák mutabilitását kihasználva a függvényekkel változtatjuk meg a lista értékét, az i szám pedig a függvény által visszaadott (új) értéket kapja:

def rule1(list, i):
    word= list[i]
    if word[-1]=='I':
        list+= [ word+'U' ]

def rule2(list, i):
    word= list[i]
    list+= [ word+word[1:] ]

def rules(list, i):
    rule1(list, i)
    rule2(list, i)
    return i+1

i= 0
list= [ 'MI' ]
while len(list)<11:
    i= rules(list, i)
print(list)

Következetesebb eljárásnak tűnik azonban, ha a dokumentációban is elsőként javasolt utat követjük: a függvény egy vektort adjon eredményül (amely tartalmazza az összes újonnan számolt értéket: a listát is, az i számot is):

def rule1(list, i):
    word= list[i]
    if word[-1]=='I':
        return [ word+'U' ]
    else:
        return []

def rule2(list, i):
    word= list[i]
    return [ word+word[1:] ]

def rules(list, i):
    list+= rule1(list, i)
    list+= rule2(list, i)
    return list, i+1

i= 0
list= [ 'MI' ]
while len(list)<11:
    print(i, list)
    list, i= rules(list, i)

Ezzel a korrekcióval a kimenet már sokkal biztatóbb alakot ölt:

0 ['MI']
1 ['MI', 'MIU', 'MII']
2 ['MI', 'MIU', 'MII', 'MIUIU']
3 ['MI', 'MIU', 'MII', 'MIUIU', 'MIIU', 'MIIII']
4 ['MI', 'MIU', 'MII', 'MIUIU', 'MIIU', 'MIIII', 'MIUIUIUIU']
5 ['MI', 'MIU', 'MII', 'MIUIU', 'MIIU', 'MIIII', 'MIUIUIUIU', 'MIIUIIU']
6 ['MI', 'MIU', 'MII', 'MIUIU', 'MIIU', 'MIIII', 'MIUIUIUIU', 'MIIUIIU', 'MIIIIU', 'MIIIIIIII']