2016-09-17 7 views
1

私は初心者のPythonの学生ですが、私はいくつかのシンプルな(しかし、今、私にとっては複雑な)演習を行っています。私はいろいろ試してみましたが、推測を止めることに決めました。なぜなら、それは学習の日常的なルーチンではないと信じているからです。Pythonエクササイズ:最後の手紙/最初の文字

私は以下の演習を解決する必要があります。

は、リスト与えられた、の 最後の文字と異なる文字で始まるリストで 最初の単語を返す、ということ、lastfirst(lst)機能を書きます前の言葉。そのような単語がない場合、 はNoneを返します。

例:

lst = ['sole','elmo','orco','alba','asta']戻り'alba'

lst = ['sky','you','use','ear','right']戻り、私はそれを解決しようとしたNone

、と私はこれでいた:

lst = ['sole','elmo','orco','alba','asta'] 

def lastfirst(lst): 

    cont = 0 
    d = 1 
    for a in lst[cont:]: 
     for b in lst[d:]:  
      if a[-1] != b[0]: 
       return lst[d] 
      else: 
       cont = cont + 1 
       d = d + 1 

print(lastfirst(lst)) 

問題私は検出されました:

プログラムでは、最初の単語の最初の文字と2番目の単語の最後の文字、または最初の単語の最後の文字と2番目の単語の最初の文字を区別することはありません。

PS:私の英語のため申し訳ありません:)

+0

'lst [i] [ - 1]'は 'lst'のアイテム' i 'を取得し、最後に_that_ itemの最後のアイテムを取得します。したがって、lst = ['sky'、 'you'、 'use'、 'ear'、 'right'] 'なら 'lst [2]'は '' use''、lst [2] [-1] 'は' 'e''、' 'use''の最後の文字です。 –

+0

ありがとうございます! :) – Nutshell93

+0

以下のいずれかの回答が問題を解決する場合は、それを受け入れる必要があります(該当する回答の横にあるチェックマークをクリックしてください)。それは2つのことをします。あなたの問題があなたの満足のために解決されたことを誰にでも知らせることができます。詳しい説明は[here](http://meta.stackexchange.com/a/5235)を参照してください。 –

答えて

2

私はそれが(のpython 3)動作すると思う:

lst = ['sole','elmo','orco','alba','asta'] 

def lastfirst(lst): 
    for i in range(len(lst)-1): 
     if lst[i][-1] != lst[i+1][0] : 
      return lst[i+1] 
    return None 
print(lastfirst(lst)) 

出力:必要

alba 

説明(修正あなたのコードで):

  • 1つのforループで2つのforループを実行する必要はありません。
  • elseステートメントで変数contをインクリメントしますが、常に同じ文字列(a)と比較します。

別の入力:

lst = ['sky','you','use','ear','right'] 

出力:

None 

は、それはあなたを助けることを願っています。

+0

@PM 2Ring私は知っているが、私は 'C++ 'のために習慣がある。とにかく感謝しています。 –

+0

ありがとうございました! – Nutshell93

1

lstのすべての単語をlstのすべての単語と比較してテストする必要がある場合は、ループをdouble forとすることがありますが、ここではそうではありません。私たちはただ一つのループを必要としており、前の単語を格納して、それを現在の単語に対してテストできるようにする必要があります。このように:

def lastfirst(lst): 
    if not lst: 
     return None 
    prev = lst[0] 
    for word in lst[1:]: 
     if word[0] != prev[-1]: 
      return word 
     prev = word 
    return None 


data = [ 
    ['sole', 'elmo', 'orco', 'alba', 'asta'], 
    ['sky', 'you', 'use', 'ear', 'right'], 
    [], 
    ['help', 'please', 'everybody', 'thanks'], 
] 

for lst in data: 
    print(lastfirst(lst)) 

出力

alba 
None 
None 
thanks 

My機能は、最初に、我々は空のリストを渡される場合

if not lst: 
    return None 

は、私たちはすぐに戻りません。それはprev = lst[0]


を行うにしようとしたときにそれ以外の場合は、プログラムがクラッシュします。ここ単線を使用してテストを行うための効率的な方法です。

def lastfirst(lst): 
    return next((v for u, v in zip(lst, lst[1:]) if u[-1] != v[0]), None) 

このコードは、明らかに、よりコンパクトに、私の以前のバージョンよりも、それは少し速くなるかもしれません。しかし、です。特にPythonを初めて使う人にとっては理解しにくいです。このような「one-liners」はもっとPythonicだと思う人もいますが、実際にはあなたのコードをできるだけ読みやすくするためにPythonのほうがいいと思う人もいます。 :)

+0

"lstのすべての単語に対してlstのすべての単語をテストする必要がある場合は、double forループを使用します。"あなたはコンビネーションのようなものを意味しました! – Nutshell93

+0

@ Nutshell93:はい、隣の単語だけでなく、 'lst'の_every_単語のペアで何かをしたいなら、二重' for'ループを使うことができます。しかし、 'itertools'モジュールは、単一の' for'ループを使っていろいろな種類の組み合わせと置換を作成する方法を持っています。 –

0

これは、itertoolsを使用したソリューションです。

まず、あなたの条件が満たされた場合にはブール値を返す関数を定義します。

def check_letters(apair): 
"In a pair, check last letter of first entry with first letter of second" 
    return apair[0][-1] == apair[1][0] 

を今、私たちはitertools moduleレシピからペアごとの機能を使用します。

import itertools 
def pairwise(iterable): 
    "s -> (s0,s1), (s1,s2), (s2, s3), ..." 
    a, b = itertools.tee(iterable) 
    next(b, None) 
    return itertools.izip(a, b) 

そして最後に:

lst = ['sole','elmo','orco','alba','asta'] 
lstlast = [item[1] for item in pairwise(lst) if not check_letters(item)] 
# returns ['alba'] 
+0

ありがとうございました!!!! – Nutshell93

関連する問題