2012-06-16 18 views
7

Jestem nowy w programowaniu i staram się rozwiązać problemy codingbat.com. Natknąłem się na ten problem:Pomijanie elementów na liście Python

Biorąc pod uwagę tablicę, oblicz sumę, z wyjątkiem sytuacji, gdy w tablicy jest 13. Jeśli w tablicy znajduje się 13, pomiń 13 i liczbę bezpośrednio za nią. Na przykład [1,2,13,5,1] powinno dać 4 (ponieważ 13 i 5 są pomijane).

To jest to, co do tej pory miałem. Moim problemem jest to, że nie wiem, co zrobić, gdy jest wiele 13 ... I chciałbym nauczyć się kodowania skutecznie. Czy możesz pomóc? (Używam Pythona 3.2) Dzięki!

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

Twój przykład powinien naprawdę dać "4", prawda? 1 + 2 + 1 = 4. – cheeken

+0

@cheeken Zmieniłem go na 4 – jamylak

+0

@ everyrybody wyścigi, aby opublikować rozwiązania: proszę sobie sprawę, że [1,2,13,5,13,13, -9,13,13,13,13 13,11,1) powinno również dać 4 ... – Will

Odpowiedz

6

Jedna trudna rzecz do zauważyć, jest coś takiego: [1, 13, 13, 2, 3]

trzeba pominąć 2 zbyt

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 

Wyjaśnienie:

Przeglądasz pozycje na liście jeden po drugim

Każdorazowe

  • Najpierw należy sprawdzić, czy jest to 13, jeśli jest, następnie zaznaczyć skip jako True, tak, że można również pominąć następny punkt.
  • drugie, sprawdzić, czy skip jest True, jeśli to, co oznacza, że ​​jest to element, tuż po 13, więc trzeba pominąć ten jeden też, i trzeba także ustawić skip powrotem do False, dzięki czemu nie zrobić pomiń następny element.
  • W końcu, jeśli nie jest to ani przypadek powyżej, należy dodać wartość do sum
+0

Czy możesz wyjaśnić tę iterację nowicjuszowi, jak ja? –

+0

@Chowza zobacz moje aktualizacje powyżej – xvatar

+0

Ah, nie zdawałem sobie sprawy, jeśli pominąć: implied, jeśli skip = True ... Dzięki! –

1

Użyj pętli while chodzić po listy, zwiększając i ręcznie. W każdej iteracji, jeśli napotkasz 13, zwiększając dwukrotnie wartość i; w przeciwnym razie, dodaj wartość do sumy roboczej i zwiększaj o jeden raz wartość i.

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

Można użyć while pętlę w leczeniu stwardnienia 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

Z jakiegoś powodu nie zadziałało to dla [13,1,2,13,2,1 , 13] ... Dało to 45 jako sumę –

+0

Myślę, że to dlatego, że ostatni element na liście to 13. Tak więc edytowałem swój kod. – plucury

3

Można użyć funkcji zip pętli wartości w parach:

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 

lub można zrobić oneliner:

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

można również użyć iteratorów:

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) 

(pierwsza lista w iZIP jest dłuższy niż sekundę, zip i iZIP ignorować dodatkowe wartości).

+0

Wow Thanks! Wygląda na to, że zadziała i po długim spojrzeniu zrozumiem to teraz. Dzięki! –

+0

Ten kod jest bardzo mało wydajny i nie działa z iteratorami :) – astynax

+0

Działa również z iteratorami! – Oren

1

myślę, że to jest najbardziej kompaktowe rozwiązanie:

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)) 

ta wykorzystuje funkcję wbudowane suma() na wyrażenie generatora. Generator generuje wszystkie elementy w sekwencji, o ile nie są 13 lub bezpośrednio po 13. Dodatkowym warunkiem "lub" jest obsłużenie pierwszego elementu w sekwencji (która nie ma poprzedniej pozycji).

1

Niektóre FP-styl :)

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 

Ten kod działa dla każdej iteracyjnej, nawet nie zapewniają swobodny dostęp bezpośredni (indeksowania) - gniazdo na przykład :)

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 

Zastosowanie:

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

Ta prosta funkcja będzie ogólnym rozwiązaniem dla Twojego pytania.

Powiązane problemy