2012-06-16 25 views
7

Sono nuovo di programmazione e sto cercando di fare i problemi codingbat.com per iniziare. Mi sono imbattuto in questo problema:elementi Saltare in un elenco Python

dato un array calcolare la somma, tranne quando c'è un 13 nella matrice. Se c'è un 13 nell'array, salta il 13 e il numero immediatamente successivo. Ad esempio [1,2,13,5,1] dovrebbe produrre 4 (poiché il 13 e il 5 sono saltati).

Questo è quello che ho finora. Il mio problema è che non so cosa fare quando ci sono più 13 ... E mi piacerebbe imparare la codifica in modo efficiente. Potete aiutare ragazzi? (Sto usando python 3.2) Grazie!

def pos(nums): 
    for i in nums: 
     if i == 13: 
      return nums.index(13) 
    return False 

def sum13(lis): 
    if pos(lis)!= False: 
     return sum(lis[:pos(lis)])+sum(lis[pos(lis)+1:]) 
    else: 
     return sum(lis) 
+1

Il tuo esempio dovrebbe dare veramente '4', giusto? 1 + 2 + 1 = 4. – cheeken

+0

@cheeken L'ho cambiato in 4 – jamylak

+0

@ chiunque gareggi per pubblicare soluzioni: si prega di rendersi conto che [1,2,13,5,13,13, -9,13,13,13,13 , 13,1,1] dovrebbe produrre anche 4 ... – Will

risposta

6

Una cosa difficile da notare è qualcosa di simile: [1, 13, 13, 2, 3]

È necessario ignorare 2 troppo

def getSum(l): 
    sum = 0 
    skip = False 
    for i in l: 
     if i == 13: 
      skip = True 
      continue 
     if skip: 
      skip = False 
      continue 
     sum += i 
    return sum 

Spiegazione:

Passa attraverso gli articoli nell'elenco uno per uno

Ogni volta che si

  • In primo luogo verificare se si tratta di 13, se lo è, allora si contrassegna come skipTrue, così che si può anche saltare voce successiva.
  • In secondo luogo, è controllare se skip è True, se lo è, che significa che è un elemento a destra dopo 13, quindi è necessario saltare questo uno troppo, ed è inoltre necessario impostare skip tornare a False in modo che non si salta l'oggetto successivo.
  • Infine, se non è neanche caso di cui sopra, si aggiunge il valore fino a sum
+0

Puoi spiegare questa iterazione per un newb come me? –

+0

@Chowza vedere i miei aggiornamenti sopra – xvatar

+0

Ah, non mi sono reso conto se saltare: implicato se skip = True ... Grazie! –

1

utilizzare un ciclo while a piedi attraverso la lista, incrementando i manualmente. Ad ogni iterazione, se si incontra un 13, incrementare i due volte; in caso contrario, aggiungere il valore a una somma parziale e incrementare i una volta.

def skip13s(l): 
    i = 0 
    s = 0 
    while (i < len(l)): 
     if l[i] == 13: 
      i += 1 
     else: 
      s += l[i] 
     i += 1 
    return s 
0

È possibile utilizzare while ciclo per il trattamento di molteplici 13.

def sum13(lis): 
    while pos(lis): 
     if pos(lis) == len(lis) - 1: 
      lis = lis[:pos(lis)] 
     else: 
      lis = lis[:pos(lis)]+lis[pos(lis)+1:] 

    return sum(lis) 
+0

Per qualche motivo questo non ha funzionato per [13,1,2,13,2,1 , 13] ... Ha dato 45 come somma –

+0

Penso che sia perché l'ultimo elemento nella lista è 13. Così ho modificato il mio codice. – plucury

3

È possibile utilizzare la funzione zip loop i valori a coppie:

def special_sum(numbers): 
    s = 0 
    for (prev, current) in zip([None] + numbers[:-1], numbers): 
     if prev != 13 and current != 13: 
      s += current 
    return s 

o si può fare un oneliner:

def special_sum(numbers): 
    return sum(current for (prev, current) in zip([None] + numbers[:-1], numbers) 
       if prev != 13 and current != 13) 

è anche possibile utilizzare iteratori:

from itertools import izip, chain 
def special_sum(numbers): 
    return sum(current for (prev, current) in izip(chain([None], numbers), numbers) 
       if prev != 13 and current != 13) 

(il primo elenco nella izip è più lungo rispetto alla seconda, zip e izip ignorare i valori in più).

+0

Wow Grazie! Questo sembra che funzionerebbe e dopo un lungo sguardo ora lo capisco. Grazie! –

+0

Questo codice è molto inefficiente di memoria e non funziona con gli iteratori :) – astynax

+0

Funziona anche con gli iteratori! – Oren

1

ritengo questa è la soluzione più compatta:

def triskaidekaphobicSum(sequence): 
    return sum(sequence[i] for i in range(len(sequence)) 
       if sequence[i] != 13 and (i == 0 or sequence[i-1] != 13)) 

Questa funzione utilizza la somma built() su un generatore di espressione. Il generatore produce tutti gli elementi nella sequenza purché non siano 13 o immediatamente dopo un 13. La condizione "o" extra è di gestire il primo elemento della sequenza (che non ha elementi precedenti).

1

Alcuni stile FP :)

def add_but_skip_13_and_next(acc, x): 
    prev, sum_ = acc 
    if prev != 13 and x != 13: 
     sum_ += x 
    return x, sum_ 

filter_and_sum = lambda l: reduce(add_but_skip_13_and_next, l, (0,0))[1] 

>>> print filter_and_sum([13,13,1,4]) 
4 
>>> print filter_and_sum([1,2,13,5,13,13,-9,13,13,13,13,13,1,1]) 
4 

Questo codice funziona per qualsiasi iteratore, anche se non forniscono l'accesso casuale (indicizzazione diretta) - Presa per esempio :)

Oneliner :)

>>> filter_and_sum = lambda l: reduce(
...  lambda acc, x: (x, acc[1] + (x if x != 13 and acc[0] != 13 else 0)), 
...  l, (0,0))[1] 
>>> print filter_and_sum([1,2,13,5,13,13,-9,13,13,13,13,13,1,1]) 
4 
0
def skipAndAddFun(inputVal, skipList): 
    sum = 0 
    for i in inputVal: 
     if not i in skipList: 
      sum += i 
    return sum 

Usage:

skipAndAddFun([1,2,13,5,1], [13, 5]) 
4 

Questa semplice funzione sarà una soluzione generica per la tua domanda.

Problemi correlati