2014-12-26 15 views
5

Stavo cercando di capire l'algoritmo di Kadane da Wikipedia, quando ho trovato questo:Python: cosa significa x in A [1:] significa?

def max_subarray(A): 
    max_ending_here = max_so_far = A[0] 
    for x in A[1:]: 
     max_ending_here = max(x, max_ending_here + x) 
     max_so_far = max(max_so_far, max_ending_here) 
    return max_so_far 

Non ho dimestichezza con Python. Ho provato a google cosa fa questa sintassi ma non sono riuscito a trovare la risposta giusta perché non sapevo come si chiamava. Ma, ho pensato A[1:] è l'equivalente di omettere A[0], così ho pensato for x in A[1:]: è equivalente a for(int i = 1; i < A.length; i++) in Java

Ma, dopo aver cambiato for x in A[1:]: a for x in range(1,len(A)), ho ottenuto il risultato sbagliato

Scusate se questa è una domanda stupida , ma non so dove altro trovare la risposta. Qualcuno può dirmi cosa fa questa sintassi e come si chiama? Inoltre, potresti darmi l'equivalente di for x in A[1:]: in Java?

+0

possibile duplicato di [Spiegazione della notazione slice di Python] (http://stackoverflow.com/questions/509211/explain-pythons-slice-notation) – Pradhan

risposta

6

Questa è la sintassi array slice. Vedi questa domanda SO: Explain Python's slice notation.

Per un elenco my_list di oggetti, ad es. [1, 2, "foo", "bar"], my_list[1:] equivale a un elenco di tutti gli elementi copiati a partire dall'indice 0 1: [2, "foo", "bar"]. Così il vostro for un'iterazione oltre questi oggetti:

for-iteration 0: x == 2 
for-iteration 1: x == "foo" 
for-iteration 2: x == "bar" 

range(..) restituisce un elenco/generatore di indici (interi), quindi la tua istruzione for avrebbe iterare su interi [1, 2, ..., len(my_list)]

for-iteration 0: x == 1 
for-iteration 1: x == 2 
for-iteration 2: x == 3 

Quindi, in questa ultima versione potrebbe utilizzare x come un indice nell'elenco: iter_obj = my_list[x].

In alternativa, una versione un po 'più divinatorio se hai ancora bisogno l'indice di iterazione (ad esempio, per il "conteggio" dell'oggetto corrente), è possibile utilizzare enumerate:

for (i, x) in enumerate(my_list[1:]): 
    # i is the 0-based index into the truncated list [0, 1, 2] 
    # x is the current object from the truncated list [2, "foo", "bar"] 

Questa versione è un futuro po' di più prova se si decide di cambiare il tipo di my_list in qualcos'altro, in quanto non si basa sui dettagli di implementazione dell'indicizzazione basata su 0, ed è quindi più probabile che funzioni con altri tipi iterabili che supportano la sintassi delle sezioni.

+0

Oh capisco. Quando ho cambiato 'per x in A [1:]' con 'per x in range (1, len (A))' Avrei dovuto accedere all'elemento usando 'A [x]' invece di solo 'x'. È questa la differenza tra 'for x in A [1:]: doSomething (x)' e 'for x in range (1, len (A)): doSomething (A [x])'? –

+0

@MargoEastham, sì, si potrebbe fare 'A [x]', invece. Si consiglia di farlo se si desidera utilizzare l'indice per qualcos'altro. La precedente sintassi è considerata più "pythonic", e la seconda più verbosa. Il precedente metodo (iterando sugli oggetti) potrebbe essere più a prova di futuro per lavorare con oggetti diversi dagli elenchi che supportano la sintassi delle sezioni. L'ultima versione presuppone l'indicizzazione nella raccolta per numeri interi a 0. Praticamente, però, non dovrebbe fare alcuna differenza. Si tratta più delle dipendenze di tipo/ipotesi e della chiarezza del codice. –

+0

Grazie. Ora so cosa è tutto su –

2

A differenza di altri linguaggi, l'iterazione su una sequenza in Python produce gli elementi all'interno della sequenza stessa. Ciò significa che iterating su [1, 2, 4] produce 1, 2 e 4 a sua volta, e non 0, 1 e 2.

+1

Esatto, quindi in Java è presente anche 'for (int x: A)' dove A è un array intero 'int []'. Potresti spiegare di più sulla differenza tra 'for x in A' e' for x in A [1:] '? Se "A [1:]" significa elemento da 1 a ultimo elemento (senza elemento zeroth). Quindi, '' x in A [1:] 'sta semplicemente iterando dall'elemento 1 all'ultimo elemento (ignorando l'elemento' A [0] '? –

+0

@MargoEastham Sì, è esattamente così: –

+0

@MargoEastham: Questo è l'effetto complessivo, ma l'effetto specifico è che viene generata una nuova sequenza che manca il primo elemento, e quindi * quella * sequenza viene iterata. –

1
A = [1, 2, 3] 

A[1:] == [2, 3] 

Questo viene utilizzato per troncare l'elenco dal primo elemento.

e si noti che le liste sono mutabili, se si trova qualcosa di simile A[:] che significa, vogliono creare un doppio di questa lista, senza alterare l'elenco originale, e utilizzare A[::-1] invece di reversed(A) per invertire la lista.

+0

Vedo. Questa è sintassi molto bella e concisa! –

9

Ecco alcuni degli esempi che ho provato

>>> a=[1,5,9,11,2,66] 

>>> a[1:] 
[5, 9, 11, 2, 66] 

>>> a[:1] 
[1] 

>>> a[-1:] 
[66] 

>>> a[:-1] 
[1, 5, 9, 11, 2] 

>>> a[3] 
11 

>>> a[3:] 
[11, 2, 66] 

>>> a[:3] 
[1, 5, 9] 

>>> a[-3:] 
[11, 2, 66] 

>>> a[:-3] 
[1, 5, 9] 

>>> a[::1] 
[1, 5, 9, 11, 2, 66] 

>>> a[::-1] 
[66, 2, 11, 9, 5, 1] 

>>> a[1::] 
[5, 9, 11, 2, 66] 

>>> a[::-1] 
[66, 2, 11, 9, 5, 1] 

>>> a[::-2] 
[66, 11, 5] 

>>> a[2::] 
[9, 11, 2, 66] 

penso che si può capire di più da questi esempi.