La funzione utilizza la comprensione degli elenchi python, senza stato?

2

Di seguito è riportata la funzione count_leaf , che accoda l'elenco mutabile branch_counts , che non è stateless.

def count_leaf(tree):
    if is_leaf(tree):
        return 1
    branch_counts = list()
    for b in tree:
        branch_counts.append(count_leaf(b))
    return sum(branch_counts)

Di seguito è riportato il programma che utilizza la comprensione degli elenchi.

def count_leaves(tree):
    if is_leaf(tree):
        return 1
    else:
        branch_counts = [count_leaves(b) for b in tree]
        return sum(branch_counts)

La funzione count_leaves utilizza la comprensione dell'elenco [count_leaves(b) for b in tree] puramente funzionale?

    
posta overexchange 16.07.2015 - 12:17
fonte

2 risposte

2

Sì, perché non c'è stato alcun mutamento dello stato. La riga branch_counts = [count_leaves(b) for b in tree] può essere interpretata come un semplice legame (come un'istruzione Let in Haskell o Lisp), poiché non ci sono ulteriori riassegnazioni o mutazioni.

Inoltre, puoi riformattarlo in questo modo per renderlo più chiaro:

def count_leaves(tree):
    return 1 if is_leaf(tree) else sum([count_leaves(b) for b in tree])
    
risposta data 16.07.2015 - 12:39
fonte
0

In questo caso puoi fingere che lo sia, ma fai attenzione. La comprensione degli elenchi crea o modifica le variabili nell'ambito circostante. (nella console ipython):

In [1]: x
NameError: name 'x' is not defined

In [2]: [x for x in range(10)]
Out[2]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

In [3]: x
Out[3]: 9

Quindi se hai qualcosa di simile

x = "foo"
[x for x ...]

x non sarà più "foo".

Si noti che questo non accade quando si utilizzano le espressioni del generatore:

In [4]: y
NameError: name 'y' is not defined

In [5]: (y for y in range(10))
Out[5]: <generator object <genexpr> at 0x7f55b7861e10>

In [6]: y
NameError: name 'y' is not defined

In [7]: y = "foo"

In [8]: y
Out[8]: 'foo'

In [9]: (y for y in range(10))
Out[9]: <generator object <genexpr> at 0x7f55b7877410>

In [10]: y
Out[10]: 'foo'

modifica: ho dimenticato di rispondere in modo chiaro alla domanda. No, non è stateless, muta lo stato localmente.

    
risposta data 16.07.2015 - 15:37
fonte

Leggi altre domande sui tag