2016-07-09 9 views
9

新しいタプルには、前の要素と次の要素の両方の要素が含まれているタプルのリスト(タプルの最初の要素によってソートされている)に新しいタプルを追加しようとしています。リスト内の要素を前と次の要素に基づいてリストに挿入する

例:

oldList = [(3, 10), (4, 7), (5,5)] 
newList = [(3, 10), (4, 10), (4, 7), (5, 7), (5, 5)] 

は、(4,10)から構成され、(、3)間及び(、7)に加えました。

Construct (x,y) from (a,y) and (x,b) 

enumerate()を使用して特定の位置に挿入しようとしましたが、実際に次の要素にアクセスすることはできません。

あなたを与えるだろう
+0

ユーザーの入力は何ですか?新しいエルムの新しい地位? –

+0

ユーザーは最初の "oldList"のみを提供します。次に、2つの古い要素の間に、新しい要素が2つの既存の要素に基づいて追加されます。 –

答えて

8
oldList = [(3, 10), (4, 7), (5,5)] 

def pair(lst): 
    # create two iterators 
    it1, it2 = iter(lst), iter(lst) 
    # move second to the second tuple 
    next(it2) 
    for ele in it1: 
     # yield original 
     yield ele 
     # yield first ele from next and first from current 
     yield (next(it2)[0], ele[1]) 

In [3]: oldList = [(3, 10), (4, 7), (5, 5)] 

In [4]: list(pair(oldList)) 
Out[4]: [(3, 10), (4, 10), (4, 7), (5, 7), (5, 5)] 

明らかに我々は異なる可能な状況に対処するために、いくつかのエラー処理を行う必要があります。

希望する場合は、また、それは、単一のイテレータを使用して行うことができます:

def pair(lst): 
    it = iter(lst) 
    prev = next(it) 
    for ele in it: 
     yield prev 
     yield (prev[0], ele[1]) 
     prev = ele 
    yield (prev[0], ele[1]) 

をあなたはITERの呼び出しの代わりにitertools.teeを使用することができます。

from itertools import tee 
def pair(lst): 
    # create two iterators 
    it1, it2 = tee(lst) 
    # move second to the second tuple 
    next(it2) 
    for ele in it1: 
     # yield original 
     yield ele 
     # yield first ele from next and first from current 
     yield (next(it2)[0], ele[1]) 
+1

ありがとう、これは魅力のように動作します。現在のリストでは機能しますが、エラー処理によってどのように改善されますか? –

+0

@ SilviuTofan、本当に空/単一タプルなどを捕まえるようなもの。あなたがそれを扱う方法は、あなたがそれらの状況で起こりたいことに依存するでしょう。 –

+0

ああ、ありがとう、ありがとう! –

5

あなたはリスト内包とitertools.chain()を使用することができます。

>>> list(chain.from_iterable([((i, j), (x, j)) for (i, j), (x, y) in zip(oldList, oldList[1:])])) + oldList[-1:] 
[(3, 10), (4, 10), (4, 7), (5, 7), (5, 5)] 
+0

あなたの答えもありがとう!私はちょうどあなたよりも少し前に投稿されたので、他のものを実装することに集中しました。 –

3

ワンライナーの大きなファンではありません(または複雑さ)自分自身、私はあなたの問題に対する非常に明白で読みやすい(これは通常良いことです!)ソリューションを提案します。

ので、非常に単純なアプローチでは、あなたがこれを行うことができます:newListにあなたの望ましい結果が得られます

def insertElements(oldList): 
    """ 
    Return a new list, alternating oldList tuples with 
    new tuples in the form (oldList[i+1][0],oldList[i][1]) 
    """ 
    newList = [] 
    for i in range(len(oldList)-1): 
     # take one tuple as is 
     newList.append(oldList[i]) 
     # then add a new one with items from current and next tuple 
     newList.append((oldList[i+1][0],oldList[i][1])) 
    else: 
     # don't forget the last tuple 
     newList.append(oldList[-1]) 
    return newList 

oldList = [(3, 10), (4, 7), (5, 5)] 
newList = insertElements(oldList) 

print(newList) 
[(3, 10), (4, 10), (4, 7), (5, 7), (5, 5)] 

をこれよりもはるかに長いコードではありませんジェネレータを使用するような洗練された(そしてメモリ効率の良い)ソリューションがあります。複雑なワンライナーよりも読みやすいと思います。また、単純な関数にいくつかのチェックを追加するのは簡単です(タプルのリストがあることを確認するなど)。

この特定のコードを最適化する必要があることがわかっていない限り(これは大きなプロジェクトの一部です)、これはgood enoughである必要があります。同時に、それは次のとおりです。実装が簡単、読みやすい、説明しやすく、維持しやすい、拡張が容易、リファクタリングしやすい、など

:他のすべての以前の答えあなたの質問にもあります多くの点で、この単純なソリューションよりも優れたソリューションです。ちょうどあなたに別の選択肢を与えたかったのです。お役に立てれば。

+0

ありがとう、私は本当にこの答えにも感謝します、それは非常に読みやすく、コードの一部を実装するのが簡単になります! –

関連する問題