Python—如何通过只保留最新的元组来消除元组列表中的重复数据。

Python—如何通过只保留最新的元组来消除元组列表中的重复数据。,python,datetime,twitter,Python,Datetime,Twitter,我有一个数据集,其中每个记录都包含用户发推的日期、他们的屏幕名称、追随者数量和朋友数量。用户可以在整个数据集中多次列出,在不同的时间列出,在不同的时间列出不同的关注者/朋友数。我想做的是获得列表中用户的唯一列表以及他们最近的关注者/朋友数。我不想在他们的屏幕名上重复数据,而是希望他们的最新值 这就是我的数据当前在重复值情况下的样子 In [14]: data Out[14]: [(datetime.datetime(2014, 11, 21, 1, 16, 2), u'AlexMatosE',

我有一个数据集,其中每个记录都包含用户发推的日期、他们的屏幕名称、追随者数量和朋友数量。用户可以在整个数据集中多次列出,在不同的时间列出,在不同的时间列出不同的关注者/朋友数。我想做的是获得列表中用户的唯一列表以及他们最近的关注者/朋友数。我不想在他们的屏幕名上重复数据,而是希望他们的最新值

这就是我的数据当前在重复值情况下的样子

In [14]: data
Out[14]: 
[(datetime.datetime(2014, 11, 21, 1, 16, 2), u'AlexMatosE', 773, 560),
 (datetime.datetime(2014, 11, 21, 1, 17, 6), u'hedofthebloom', 670, 618),
 (datetime.datetime(2014, 11, 21, 1, 18, 8), u'hedofthebloom', 681, 615),
 (datetime.datetime(2014, 11, 21, 1, 19, 1), u'jape2116', 263, 540),
 (datetime.datetime(2014, 11, 21, 1, 19, 3), u'_AlexMatosE', 790, 561),
 (datetime.datetime(2014, 11, 21, 1, 19, 5), u'Buffmuff69', 292, 270),
 (datetime.datetime(2014, 11, 21, 1, 20, 1), u'steveamodu', 140, 369),
 (datetime.datetime(2014, 11, 21, 1, 20, 9), u'jape2116', 263, 540),
 (datetime.datetime(2014, 11, 21, 1, 21, 3), u'chighway', 363, 767),
 (datetime.datetime(2014, 11, 21, 1, 22, 9), u'jape2116', 299, 2000)]
这是我获取数据中唯一用户的方法

In [15]: users = set(sorted([line[1] for line in data]))
现在我需要弄清楚如何为数据集中的每个唯一用户获取最新的一组值。我不确定for循环是最好的方式还是其他方式更好。

In [18]: most_recent_user_data = [] 
   ....: for line in data:
   ....:     if line[1] in users:
   ....:         ...
   ....:         ...
   ....:         ...
   ....:         most_recent_user_data.append((line[1], line[2], line[3]))
Ultimate,我希望每个唯一的用户都有一次机会,他们最近的追随者/朋友都很有价值

In [19]: most_recent_user_data
Out[19]: 
 (u'hedofthebloom', 681, 615),
 (u'_AlexMatosE', 790, 561),
 (u'Buffmuff69', 292, 270),
 (u'steveamodu', 140, 369),
 (u'chighway', 363, 767),
 (u'jape2116', 299, 2000)]

一种方法是使用字典和用户名作为键。对于每个键,都有一个用户数据列表,可以根据需要进行排序。以下是一种方法:

from collections import defaultdict

# move data to a dict
dataDict = defaultdict(list)

for v in data:
    dataDict[v[1]] += [v]

# sort user data for each user/key 
for u,v in dataDict.items():
    dataDict[u] = sorted(v, reverse=True)   

# get first (i.e. most recent) values for each user       
for u,v in dataDict.items():
    print(u,v[0][-2], v[0][-1])    
结果是:

(u'chighway', 363, 767)
(u'AlexMatosE', 773, 560)
(u'hedofthebloom', 681, 615)
(u'steveamodu', 140, 369)
(u'Buffmuff69', 292, 270)
(u'_AlexMatosE', 790, 561)
(u'jape2116', 299, 2000)

使用字典存储每个用户的最新数据

latests = {}
for d in data:
    if d[0] > latests.setdefault(d[1], d)[0]:
        latests[d[1]] = d

results = [(d[1], d[2:]) for d in latests.values()]
from pprint import pprint
pprint(results)

获得所需结果的另一种方法:

from operator import itemgetter

# sort the data using time as the key
data.sort(key=itemgetter(0), reverse=True)

# remove duplicated users from the data
def uniq(seq):
    seen = set()
    seen_add = seen.add
    return [(x[1], x[2], x[3]) for x in seq if not (x[1] in seen or seen_add(x[1]))]

uniq(data)
其中:

[('jape2116', 299, 2000),
 ('chighway', 363, 767),
 ('steveamodu', 140, 369),
 ('Buffmuff69', 292, 270),
 ('_AlexMatosE', 790, 561),
 ('hedofthebloom', 681, 615),
 ('AlexMatosE', 773, 560)]

我正在使用中提到的方法。

您可以在
itertools
模块中使用
groupby
函数:

import datetime
import itertools

data = [(datetime.datetime(2014, 11, 21, 1, 16, 2), u'AlexMatosE', 773, 560),
        (datetime.datetime(2014, 11, 21, 1, 17, 6), u'hedofthebloom', 670, 618),
        (datetime.datetime(2014, 11, 21, 1, 18, 8), u'hedofthebloom', 681, 615),
        (datetime.datetime(2014, 11, 21, 1, 19, 1), u'jape2116', 263, 540),
        (datetime.datetime(2014, 11, 21, 1, 19, 3), u'_AlexMatosE', 790, 561),
        (datetime.datetime(2014, 11, 21, 1, 19, 5), u'Buffmuff69', 292, 270),
        (datetime.datetime(2014, 11, 21, 1, 20, 1), u'steveamodu', 140, 369),
        (datetime.datetime(2014, 11, 21, 1, 20, 9), u'jape2116', 263, 540),
        (datetime.datetime(2014, 11, 21, 1, 21, 3), u'chighway', 363, 767),
        (datetime.datetime(2014, 11, 21, 1, 22, 9), u'jape2116', 299, 2000)]

# sorted record by name and datetime
data = sorted(data, key=lambda x: (x[1], x[0]), reverse=True)

# group by username and get the most recent user data
most_recent_user_data = [[(lambda x: (x[1], x[2], x[3]))(next(v)) for k, v in itertools.groupby(data, key=lambda x: x[1])]]
结果:

[('steveamodu', 140, 369),
 ('jape2116', 299, 2000), 
 ('hedofthebloom', 681, 615),
 ('chighway', 363, 767), 
 ('_AlexMatosE', 790, 561),
 ('Buffmuff69', 292, 270), 
 ('AlexMatosE', 773, 560)]

仅当用户第一次出现时,才按相反的时间顺序对数据集进行排序,并将其添加到字典或附加到列表中:

import datetime    
users = {}
for d in reversed(data):
    if d[1] not in users: users[d[1]] = tuple(d[2:])

# {'_AlexMatosE': (790, 561), 'steveamodu': (140, 369), 'jape2116': (299, 2000), 'chighway': (363, 767), 'AlexMatosE': (773, 560), 'hedofthebloom': (681, 615), 'Buffmuff69': (292, 270)}

您是否尝试过按用户分组、按时间戳排序以及获取最近的一个?