Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 筛选列表中的最新项目_Python_List_Dictionary_Lambda - Fatal编程技术网

Python 筛选列表中的最新项目

Python 筛选列表中的最新项目,python,list,dictionary,lambda,Python,List,Dictionary,Lambda,我有一个Python的大型数据结构,基本上是一个字典列表。这些字典中的每一个都可能包含一些重复出现的属性和时间戳。我试图查看这些属性的值是否相同,如果相同,则只获取具有最新时间戳的字典。例如: [{'data': '3.50.1', 'date_time': '20131213-100308', 'version': '8.0.22'}, {'data': '3.50.1', 'date_time': '20131230-100308', 'version': '8.0.22'}, {'da

我有一个Python的大型数据结构,基本上是一个字典列表。这些字典中的每一个都可能包含一些重复出现的属性和时间戳。我试图查看这些属性的值是否相同,如果相同,则只获取具有最新时间戳的字典。例如:

[{'data': '3.50.1', 'date_time': '20131213-100308', 'version': '8.0.22'},
 {'data': '3.50.1', 'date_time': '20131230-100308', 'version': '8.0.22'},
 {'data': '3.47.0', 'date_time': '20131213-150410', 'version': '8.0.21'}]
字典包含更多的字段,但假设这些字段是可能重复出现的常见字段。在这种情况下,上面的列表应该被过滤到只有两个目录-第二个和第三个。有没有什么聪明的方法可以在不做双for循环的情况下实现这一点


我尝试过使用lambda函数和Python的过滤器,但没有效果。

尝试类似的方法

def findLatestDict(lst):
    latestDict = lst[0]
    latestTime = latestDict["date_time"]

    sameTimeList = []

    for aDict in lst:
        if aDict["date_time"] > latestTime:
            latestTime = aDict["date_time"]
            latestDict = aDict
            sameTimeList = []
        elif aDict["date_time"] == latestTime:
            sameTimeList.append(aDict)

    return (latestDict, sameTimeList)

此函数将返回它找到的具有最新时间戳的第一个dict,以及具有相同时间戳的所有其他dict的列表。

尝试类似的操作

def findLatestDict(lst):
    latestDict = lst[0]
    latestTime = latestDict["date_time"]

    sameTimeList = []

    for aDict in lst:
        if aDict["date_time"] > latestTime:
            latestTime = aDict["date_time"]
            latestDict = aDict
            sameTimeList = []
        elif aDict["date_time"] == latestTime:
            sameTimeList.append(aDict)

    return (latestDict, sameTimeList)

此函数将返回它找到的带有最新时间戳的第一个dict,以及具有相同时间戳的所有其他dict的列表。

如果对数据进行了适当排序,最好使用itertools.groupby。
如果数据未排序,您可以执行以下操作:

data = [
    {'data': '3.50.1', 'date_time': '20131213-100308', 'version': '8.0.22'},
    {'data': '3.50.1', 'date_time': '20131230-100308', 'version': '8.0.22'},
    {'data': '3.47.0', 'date_time': '20131213-150410', 'version': '8.0.21'},
]

def filtered(data):
    temp = dict()
    for row in data:

        # decorate
        stamp = row.pop('date_time')
        key = tuple(sorted(row.items()))

        # filter
        if temp.get(key, '')<stamp:
            temp[key] = stamp

    # undecorate
    for key, stamp in temp.items():
        d = dict(key)
        d['date_time'] = stamp
        yield d

for row in filtered(data):
    print row
数据=[
{'data':'3.50.1','date_time':'20131213-100308','version':'8.0.22'},
{'data':'3.50.1','date_time':'20131230-100308','version':'8.0.22'},
{'data':'3.47.0','date_time':'20131213-150410','version':'8.0.21'},
]
def已过滤(数据):
temp=dict()
对于数据中的行:
#装饰
stamp=row.pop('date\u time')
key=tuple(已排序(row.items()))
#滤器

如果临时获取(键“”)如果数据被正确排序,最好使用itertools.groupby.
如果数据未排序,您可以执行以下操作:

data = [
    {'data': '3.50.1', 'date_time': '20131213-100308', 'version': '8.0.22'},
    {'data': '3.50.1', 'date_time': '20131230-100308', 'version': '8.0.22'},
    {'data': '3.47.0', 'date_time': '20131213-150410', 'version': '8.0.21'},
]

def filtered(data):
    temp = dict()
    for row in data:

        # decorate
        stamp = row.pop('date_time')
        key = tuple(sorted(row.items()))

        # filter
        if temp.get(key, '')<stamp:
            temp[key] = stamp

    # undecorate
    for key, stamp in temp.items():
        d = dict(key)
        d['date_time'] = stamp
        yield d

for row in filtered(data):
    print row
数据=[
{'data':'3.50.1','date_time':'20131213-100308','version':'8.0.22'},
{'data':'3.50.1','date_time':'20131230-100308','version':'8.0.22'},
{'data':'3.47.0','date_time':'20131213-150410','version':'8.0.21'},
]
def已过滤(数据):
temp=dict()
对于数据中的行:
#装饰
stamp=row.pop('date\u time')
key=tuple(已排序(row.items()))
#滤器

如果temp.get(key,)如果记录已经“分组”在一起,即要从中选择的记录是相邻的,您可以简单地使用,
max()
key=lambda rec:rec['date\u time']
来选择每个组中最近的记录(请注意,时间戳表示为字符串的方式,可以方便地按字典进行比较):

如果它们尚未组合在一起,则可以先对它们进行排序(可能效率低下),如:

或者,在上述解决方案中,使用类似于
groupby
的非itertools替代
itertools.groupby

def groupby(seq, func):
    groups = {}
    for x in seq:
        y = func(x)
        groups.setdefault(y, []).append(x)
    return groups

如果您要求“数据”和“版本”字段应相同,请将对
groupby
的调用更改为:
groupby(rec,lambda rec:(rec['data'],rec['version']):

如果记录已经“分组”在一起,即要从中选择的记录是相邻的,您可以简单地使用,
max()
使用
key=lambda rec:rec['date\u time']
选择每个组中最近的一个(注意时间戳表示为字符串的方式,可以方便地按字典顺序进行比较):

如果它们尚未组合在一起,则可以先对它们进行排序(可能效率低下),如:

或者,在上述解决方案中,使用类似于
groupby
的非itertools替代
itertools.groupby

def groupby(seq, func):
    groups = {}
    for x in seq:
        y = func(x)
        groups.setdefault(y, []).append(x)
    return groups


如果您要求“数据”和“版本”字段应相同,请将对
groupby
的调用更改为:
groupby(recs,lambda rec:(rec['data'],rec['version'])):

列表是否按照重复值始终位于相邻项的意义进行排序?每个
dict
是否都将具有相同的键,或者可能有更多、更少或不同的键?此外,您说您想要相同“数据”的最新值但是这里的第一个dict有一个更早的日期?Lev,不一定。它们是按一定的顺序插入的,但我不确定JSON决定如何存储它。tjiko,每个dict都有相同的键。对不起,我的意思是第二个dict不是第一个。我更正了错误。列表排序的意义是重复值总是在neighb中吗或者项目?每个
dict
都会有相同的键,还是会有更多、更少或不同的键?另外,你说你想要相同“数据”的最新版本但是这里的第一个
dict
有一个更早的日期?Lev,不一定。它们是按一定的顺序插入的,但我不确定JSON决定如何存储它。tjiko,每个dict都有相同的键。对不起,我的意思是第二个dict不是第一个。我更正了错误。比较列表中每一个字典的时间戳对我们没有多大帮助当我只想比较具有一组共同的键值对的dict的时间戳时,你可以将具有某些键值对的子列表传递给这个函数,找出该子列表是问题的一部分。@rexbelia你可以很容易地通过管道理解:{key:aDict[key]对于aDict.keys()中的键,如果aDict[key]==val}明白了,我可以用你喜欢的方式更新我的答案,但是看起来itertools的答案非常适合你。当我只想比较具有一组常见键值对的dict的时间戳时,比较列表中每个字典的时间戳对我来说没有多大用处。然后你可以传递该子列表这个函数有特定的键值对。很好,找出子列表是问题的一部分。@rexbelia你可以很容易地通过管道理解做到这一点:{key:aDict[key]for key in aDict.keys(),如果aDict[key]==val}得到它,我可以在一点时间内更新我的答案