2012-04-17 133 views
2

返回數組的總和,除了忽略以6開頭的數字部分並延伸到下一個7(每6個會跟着至少一個7) 。沒有號碼返回0。尋找一個更優雅的解決方案

sum67([1, 2, 2]) ? 5 
sum67([1, 2, 2, 6, 99, 99, 7]) ? 5 
sum67([1, 1, 6, 7, 2]) ? 4 
def sum67(nums): 
    dontadd = 0 
    sum = 0 
    for i in range(0, len(nums)): 
     if dontadd == 0: 
      if nums[i] == 6: 
       dontadd = 1 
      else: 
       sum += nums[i] 
     else: 
      if nums[i] == 7: 
       dontadd = 0 
      else: 
       pass# nothing happens. It is useful as a placeholder when a statement is required syntactically 
    return sum 

尋找從codingbat一個更優雅的解決這個問題。這個答案似乎並不直觀,因爲它可能是

+2

類似這樣的問題屬於無論是在http://codereview.stackexchange.com/如果你想要全面改善,或http:// codegolf.stackexchange.com/如果你想看到其他解決方案的「難題」 – agf 2012-04-17 05:19:58

+2

我正在投票關閉這個問題作爲題外話,因爲它要求推薦一個「更優雅」的解決方案的工作代碼,它應該最好在codereview上。 – 2016-10-28 14:42:47

回答

6

如果我們可以刪除我們不想要的元素,那麼我們可以使用一個簡單的總和。這裏是一個例子:

def sum67(nums): 
    nums=nums[:] 
    while 6 in nums: 
     i=nums.index(6) 
     j=nums.index(7,i) 
     del nums[i:j+1] 
    return sum(nums) 

首先,我們使用nums=nums[:]複製。來電者可能不希望nums更改。

nums.index(6)找到值爲6的第一個元素的索引。nums.index(7,i)找到索引爲i後第一個具有值7的元素的索引。 del nums[i:j+1]然後刪除範圍從ij的元素,包括j處的元素。

+0

我喜歡乾淨的簡單。 – steveha 2012-04-17 04:15:12

+0

這似乎是對我使用pop的方法的嚴格改進。 – 2012-04-17 04:17:07

+0

是的,這是一個不錯的 – davidjglynn 2012-04-17 05:04:58

1

此版本不會修改列表。

def sum67(xs): 
    xs = iter(xs) 
    s = 0 
    for x in xs: 
    if x == 6: 
     while x != 7: 
      x = xs.next() 
    else: 
     s += x 
    return s 
3

這是不是太糟糕(你可能認爲它試圖太聰明,雖然)。

>>> def sum67(nums): 
...  while 6 in nums: 
...   index = nums.index(6) 
...   while nums.pop(index) != 7: 
...    pass 
...  return sum(nums) 
... 
>>> sum67([1, 2, 3]) 
6 
>>> sum67([1, 2, 2, 6, 99, 99, 7]) 
5 
>>> sum67([1, 1, 6, 7, 2]) 
4 
>>> sum67([1, 2, 2, 6, 99, 99, 7, 8, 1, 6, 0, -1000, 7, 2]) 
16 

這裏是一個非常愚蠢的一個(不會與負數工作)

>>> import re 
>>> def sum67(nums): 
...  return sum(int(j) for j in re.sub(r'6\d*?7', '', ''.join((str(i) for i in nums)))) 
>>> sum67([1, 2, 3]) 
6 
>>> sum67([1, 2, 2, 6, 99, 99, 7]) 
5 
>>> sum67([1, 2, 2, 6, 99, 99, 7, 8, 1, 6, 0, 7, 2]) 
16 

請永遠不要寫這樣的代碼:對

一個更可怕的一個班輪在我離開之前單憑這一點:

>>> def sum67(nums): 
...  return sum(i if i != 6 else -sum(nums[pos+1:nums.index(7,pos)+1]) for pos, i in enumerate(nums)) 
... 
>>> sum67([1, 2, 2, 6, 99, 99, 7]) 
5 
>>> sum67([1, 2, 2, 6, 99, 99, 7, 8, 1, 6, 0, -1000, 7, 2]) 
16 
+0

這會修改原始列表,但效果很好。感謝您向我公開一些新的'list'方法! – 2012-04-17 03:55:34

+0

@MarkRansom如果你不想修改原來的列表,你可以在方法的開始放置'nums = nums [:]'或其他東西。實際上這是一個好點,我沒有真正想過更改列表的問題。 – 2012-04-17 03:56:41

1
def sum67(nums): 
    i=0 
    sum=0 
    n=len(nums) 
    while i<n: 
    if nums[i]==6: 
     i=nums.index(7,i) 
    else: 
     sum += nums[i] 
    i+=1 
    return sum 
1

我的解決方案將無法從OP太大的不同,但總的來說,我喜歡的總是有存在的添加操作,只是有邏輯切換1和0

之間的「ACCUM」的價值理念
def sum67(nbrs): 
    total = 0 
    accum = 1 
    for nbr in nbrs: 
     if nbr==6: 
      accum=0 
     total += nbr*accum 
     if accum==0 and nbr==7: 
      accum=1 
    return total 
0

這裏是可以容易理解的一個版本:

def sum67(nums): 
    found6 = False 
    result = 0 
    for n in nums: 
     if n==6: 
      found6 = True 
      continue 
     if n==7 and found6: 
      found6 = False 
      continue 
     if not found6: 
      result += n 
    return result 
3

我最喜歡的Python的事情是,它使得它很容易打散的一個問題。

def skip67(seq): 
    skipping = False 
    for value in seq: 
     skipping = skipping or value == 6 
     yield 0 if skipping else value 
     skipping = skipping and value != 7 

def sum67(seq): 
    return sum(skip67(seq)) 

>>> sum67([1, 2, 2]) 
5 
>>> sum67([1, 2, 2, 6, 99, 99, 7]) 
5 
>>> sum67([1, 1, 6, 7, 2]) 
4 
+2

沒有必要產生0值。你可以在'for'循環中做第二行,就是'如果不跳過:yield value'除了挑選,我喜歡它。特別是我喜歡這個解決方案可以與迭代器一起工作,而不需要強制中間列表! – steveha 2012-04-17 04:11:33

+0

@steveha,我認爲。我有點喜歡輸入和輸出序列長度相同,但最終它並不重要。 – 2012-04-17 04:13:07

1
def sum67(L): 
    it = iter(L) 
    return sum(all(i!=7 for i in it) if i == 6 else i for i in it) 

如果你有興趣在如何工作稍微更可讀的版本:

def slice67(L): 
    it = iter(L) 

    for i in it: 
     if i != 6: 
      yield i 
     else: 
      while next(it, 7) != 7: 
       pass 

print sum(slice67([1, 2, 2])) 
+0

+1這真棒,但你可以刪除'和0',因爲OP說每6個匹配一個7。 – jamylak 2012-04-17 05:46:58

0

這個怎麼樣?

>>> def sum67(l): 
...  sum = 0 
...  add = True 
...  for i in l: 
...   add = add and (i != 6) 
...   sum += add and i or 0 
...   add = add or i == 7 
...  return sum 
... 
>>> print sum67([1, 2, 3]) 
6 
>>> print sum67([1, 2, 2, 6, 99, 99, 7]) 
5 
>>> print sum67([1, 1, 6, 7, 2]) 
4 
>>> print sum67([1, 2, 2, 6, 99, 99, 7, 8, 1, 6, 0, -1000, 7, 2]) 
16 

它利用了Python計算布爾表達式第一操作數的值確定的結果,例如,實際上,在sum += add and i or 0,如果addFalse,它進入or部分和的計算結果爲0,如果add分別爲True,則評估爲i

0
def sum67(nums): 
    while 6 in nums: 
    for x in nums[nums.index(6):]: 
     nums.remove(x) 
     if x == 7: 
     break 
    return sum(nums) 
0

一個班輪與列表解析:

def sum67(nums): return sum([x for index, x in enumerate(nums) if (((nums[(index - nums[index::-1].index(6)):].index(7) + (index - nums[index::-1].index(6))) < index) if (6 in nums[:index+1]) else True)])