2017-12-20 8 views
2

一意のIDを持つタプルのリストを返したいが、特に最新のタプルを保持する。最大値に基づいて一意の要素を持つタプルのリストを返すにはどうすればよいですか?

一意のIDは、各タプルの最初の要素(1,2,3,4)にあります。

日付は、各タプルの1つ以上の要素に存在します(第3要素&タプルの第6要素)。

a = [(1,'Y', 'rat', datetime.datetime(2016, 12, 12, 0, 0), 'N', None), 
(2,'Y', 'ox', datetime.datetime(2017, 9, 4, 0, 0), 'N', None), 
(1,'N', None, None, 'Y', datetime.datetime(2017, 9, 17, 0, 0)), 
(2,'N', None, None, 'Y', datetime.datetime(2017, 3, 16, 0, 0)), 
(3,'Y', 'tiger', datetime.datetime(2013, 1, 18, 0, 0), 'N', None), 
(4,'N', None, None, 'Y', datetime.datetime(2017, 10, 3, 0, 0))] 

私は期待していた出力は次のようになります。

b = [(1,'N', None, None, 'Y', datetime.datetime(2017, 9, 17, 0, 0)), 
(2,'Y', 'ox', datetime.datetime(2017, 9, 4, 0, 0), 'N', None), 
(3,'Y', 'tiger', datetime.datetime(2013, 1, 18, 0, 0), 'N', None), 
(4,'N', None, None, 'Y', datetime.datetime(2017, 10, 3, 0, 0))] 

私は辞書にタプルを入れて、GROUPBYを使用して並べ替えられました。

{1: [(1, 'Y', 'rat', datetime.datetime(2016, 12, 12, 0, 0), 'N', None), 
(1, 'N', None, None, 'Y', datetime.datetime(2017, 9, 17, 0, 0))], 
2: [(2, 'Y', 'ox', datetime.datetime(2017, 9, 4, 0, 0), 'N', None), 
(2, 'N', None, None, 'Y', datetime.datetime(2017, 3, 16, 0, 0))], 
3: [(3, 'Y', 'tiger', datetime.datetime(2013, 1, 18, 0, 0), 'N', None)], 
4: [(4, 'N', None, None, 'Y', datetime.datetime(2017, 10, 3, 0, 0))]} 

私はトラブル私は新しいリストにしたい辞書の値を抽出が生じています。この段階から:

from itertools import groupby 
dict={} 
f = lambda x: x[0] 
for key, group in groupby(sorted(a, key=f),f): 
    dict[key] = list(group) 

これは、辞書の出力です。

ご協力いただきありがとうございます。

+1

はStackOverflowのへようこそ!あなたが問題を解決しようとしたコードスニペットを提供すれば、コミュニティからの支援を得る可能性は非常に高いです。 – Maciej

+0

「最新の日付でタプルを保つ」とはどういう意味ですか?どこに? –

+0

これは密接に関連している可能性があります:https://stackoverflow.com/questions/3922644/find-oldest-youngest-datetime-object-in-a-list#3922675 – jmunsch

答えて

4

最初に、その位置に関係なく、タプルからdatetimeを取得する関数を定義できます。 その後、idとdatetimeでリストをソートし、IDでグループ化し、次のエントリを取得して、再度ソートすることができます(IDでソートされます)。

>>> getdate = lambda t: next(x for x in t if isinstance(x, datetime.datetime)) 
>>> sorted(next(g) for k, g in itertools.groupby(sorted(a, key=lambda t: (t[0], getdate(t)), reverse=True), key=lambda t: t[0])) 
[(1, 'N', None, None, 'Y', datetime.datetime(2017, 9, 17, 0, 0)), 
(2, 'Y', 'ox', datetime.datetime(2017, 9, 4, 0, 0), 'N', None), 
(3, 'Y', 'tiger', datetime.datetime(2013, 1, 18, 0, 0), 'N', None), 
(4, 'N', None, None, 'Y', datetime.datetime(2017, 10, 3, 0, 0))] 

少し短く、IDで1回だけソートしてmaxを日付で取得してください。同じ結果:

>>> [max(g, key=getdate) for k, g in itertools.groupby(sorted(a), key=lambda t: t[0])] 

もちろん、同じことがまた可能である(そして速い)単純なループと辞書と...

d = dict() 
for t in a: 
    if t[0] not in d or getdate(d[t[0]]) < getdate(t): 
     d[t[0]] = t 

...ちょっとは、何もovercomplicatedを打ちます1ライナー!

0

私には、カスタムコードを書く必要があります。 Pythonには、達成したいことをするための組み込み関数はありません。

古典的なPythonコードまたはPandasなどのデータ指向のライブラリを使用できます。

主なアイデアは、これは単なるグローバルかつ汎用的な考えですが、私は詳細をしないこの1

result = dict() 

for item in a: 
    if item[0] not in result: 
    result[item[0]] = ... 
    else: 
    if result[item[0]][5] < item[5]: 
     result[item[0]] = ... 

です。

+0

日付が常に[5]の位置にあるとは限りません。あなたが望むならそれをあなたのdictのアプローチと組み合わせる機能。 –

+0

私はあなたのために仕事をするつもりはありません。私はあなたに必要な知識や、あなたの必要性に答えるための実現可能なアプローチを与えることをやめます。 –

0

あなたはこれを試すことができます。

import datetime 
import itertools 
a = [(1,'Y', 'rat', datetime.datetime(2016, 12, 12, 0, 0), 'N', None), 
(2,'Y', 'ox', datetime.datetime(2017, 9, 4, 0, 0), 'N', None), 
(1,'N', None, None, 'Y', datetime.datetime(2017, 9, 17, 0, 0)), 
(2,'N', None, None, 'Y', datetime.datetime(2017, 3, 16, 0, 0)), 
(3,'Y', 'tiger', datetime.datetime(2013, 1, 18, 0, 0), 'N', None), 
(4,'N', None, None, 'Y', datetime.datetime(2017, 10, 3, 0, 0))] 
new_s = [d for c, d in [(a, sorted(list(b), key=lambda x:[h for h in x if type(h) == type(datetime.datetime(2017, 9, 17, 0, 0))][0], reverse=True)[0]) for a, b in itertools.groupby(sorted(a, key=lambda x:x[0]), key=lambda x:x[0])]] 

出力:

[(1, 'N', None, None, 'Y', datetime.datetime(2017, 9, 17, 0, 0)), (2, 'Y', 'ox', datetime.datetime(2017, 9, 4, 0, 0), 'N', None), (3, 'Y', 'tiger', datetime.datetime(2013, 1, 18, 0, 0), 'N', None), (4, 'N', None, None, 'Y', datetime.datetime(2017, 10, 3, 0, 0))] 
関連する問題