2016-06-17 13 views
3

私はリストをループしようとしていますが、同時に私が比較できるようにする前に項目を参照しています。私のList1タプルを通して私がループしたいリストの前の項目を参照するPython

list1=[(1,'a','hii'),(2,'a','byee'),(3,'a','yoo'),(4,'b','laa'),(5,'a','mehh')] 

なタプルの第二の値は、前の組の2番目の値と同じ値である場合に(両方=:

は、これは私のコードです= 'a')、タプルの3番目の項目を連結します。私はをしたい

出力:

list2=[('a','hii,byee,yoo'),('b','laa'),('a','mehh')] 

私はを試してみました何:

for item in list1: 
    for item2 in list2: 
      if item[0]==(item2[0]-1) and item[1]==item2[1]: 
        print item[2]+','+item2[2] 
      elif item[0] != item2[0]-1: 
        continue 
      elif item[0]==(item2[0]-1) and item[1] != item2[1]: 
        print item[2] 

間違った出力

hii,byee 
byee,yoo 
yoo 
laa 

最初の2つの出力から、ループは前の値だけを見ているが、2つ以上の前の値は見ていないようです。それゆえ、それは一緒に2つの単語を結合し、3つではありませんでした。また、出力には繰り返しがあります。

どうすればこの問題を回避できますか?

+0

ドゥ実際には隣接するタプルをマージしたいだけですか?つまり、最初の3つはすべてマージされますが、最後のものは「mehh」と一緒にリストの先頭からマージされません。 – Blckknght

+0

これは隣接していなければならず、タプルの2番目の値は同じでなければなりません(== 'a'または他の値の両方)。タプルの最初の項目は前の項目より1大きくなければなりません。要件を満たしていれば、最初は3回、最初は「n回」とする。また、私のリストはすでにタプルの最初の値でソートされています。 – jxn

答えて

4

私は

list1 = [(1,'a','hii'),(2,'a','byee'),(3,'a','yoo'),(4,'b','laa'),(5,'a','mehh')] 
list2 = [(1,'a','hii'),(3,'a','byee'),(4,'a','yoo'),(5,'b','laa'),(6,'a','mehh')] 
list3 = [(1,'a','hoo'),(3,'a','byee'),(5,'a','yoo'),(6,'a','laa'),(7,'a','mehh'),(9, 'b', 'nope')] 

for l in (list1, list2, list3): 
    print "IN:", l 
    print "OUT:", combine(l) 
    print 

OUTPUT

IN: [(1, 'a', 'hii'), (2, 'a', 'byee'), (3, 'a', 'yoo'), (4, 'b', 'laa'), (5, 'a', 'mehh')] 
OUT: [('a', 'hii,byee,yoo'), ('b', 'laa'), ('a', 'mehh')] 

IN: [(1, 'a', 'hii'), (3, 'a', 'byee'), (4, 'a', 'yoo'), (5, 'b', 'laa'), (6, 'a', 'mehh')] 
OUT: [('a', 'hii'), ('a', 'byee,yoo'), ('b', 'laa'), ('a', 'mehh')] 

IN: [(1, 'a', 'hoo'), (3, 'a', 'byee'), (5, 'a', 'yoo'), (6, 'a', 'laa'), (7, 'a', 'mehh'), (9, 'b', 'nope')] 
OUT: [('a', 'hoo'), ('a', 'byee'), ('a', 'yoo,laa,mehh'), ('b', 'nope')] 

これは、両方の保証の世話をする...それは

def combine(inval): 
    outval = [inval[0]] 
    for item in inval[1:]: 
     if item[0] == outval[-1][0] + 1 and item[1] == outval[-1][1]: 
      outval[-1] = (item[0], item[1], ",".join([outval[-1][2], item[2]])) 
      continue 
     outval.append(item) 
    return [(item[1], item[2]) for item in outval] 

そして、それをテストすることを必要以上にこのよう難しくなっていました0番目のインデックスの連続番号と1番目のインデックスの等しい値。

+0

インデックス0の項目がシーケンシャルであることについて、これまで何も気付かなかった。これは少し変わるでしょう。 – sberry

+0

はるかに簡単で実用的なソリューションでEDITを参照してください。 – sberry

2

編集:要件に応じてアルゴリズムを更新しました。 group(values、sort = True)を呼び出すことで、同じキーを持つすべてのタプルをグループ化することも、group(value)を呼び出して同じキーを持つ隣接タプルだけをグループ化することもできます。このアルゴリズムは、3番目の要素だけを取得するのではなく、最後のタプルのキーの後にあるすべての要素も収集します。

GroupByでこれがうまくいきます。タプルの2番目の要素で値をグループ化できます。そして、各グループごとに、グループ内の第三のすべての要素を取得し、1つの文字列にそれらを結合:

import itertools 

def keySelector(tup): 
    return tup[1] 

def group(values, sort=False): 
    """ 
    Group tuples by their second element and return a list of 
    tuples (a, b) where a is the second element and b is the 
    aggregated string containing all of the remaining contents 
    of the tuple. 

    If sort=True, sort the tuples before grouping. This will 
    group all tuples with the same key. Otherwise, only adjacent 
    tuples wth the same key will be grouped. 
    """ 

    if sort: 
     values.sort(key=keySelector) 

    grouped = itertools.groupby(values, key=keySelector) 

    result = [] 
    for k, group in grouped: 

     # For each element in the group, grab the remaining contents of the tuple 
     allContents = [] 
     for tup in group: 
      # Convert tuple to list, grab everything after the second item 
      contents = list(tup)[2:] 
      allContents.extend(contents) 

     # Concatenate everything into one string 
     aggregatedString = ','.join(allContents) 

     # Add to results 
     result.append((k, aggregatedString)) 

    return result 

vals = [(1,'a','hii','abc','def'), 
     (2,'a','byee'), 
     (3,'a','yoo'), 
     (4,'b','laa'), 
     (5,'a','mehh','ghi','jkl')] 

print(group(vals, sort=True)) 

出力:リスト内包と

[('a', 'hii,abc,def,byee,yoo,mehh,ghi,jkl'), ('b', 'laa')] 

短縮バージョン:

def getGroupContents(tuples): 
    return ','.join(item for tup in tuples for item in list(tup)[2:]) 

def group(values, sort=False): 
    if sort: 
     values.sort(key=keySelector) 

    grouped = itertools.groupby(values, key=keySelector) 
    return [(k, getGroupContents(tuples)) for k, tuples in grouped] 
+0

'keySelector'を[itemgetter(1)'](https://docs.python.org/2/library/operator.html#operator.itemgetter)に置き換えることができます。それはグループ第二の要素によってではなく、最後の1 '(5、「」、「MEHH」)で取ることができるということですどのように –

+0

'? – jxn

+0

また、他のアイテムをタプルに保持するにはどうしたらいいですか?以下のような私のタプルは(5、「」、「MEHH」、「XYZ」、「ABC」)を持っていたと私は出力にそれをすべて持っているしたい場合は? – jxn

関連する問題