0

我有一个列表列表,例如:

nodes =[[nodeID,x,y,z],....]

我想找到:

xi,yi for zi=zmax given zmax= max z for same x,y

并将其存储(xi,yi,zi)在另一个列表中。

我可以这样做:

nodes=[[literal_eval(x) for x in item] for item in nodes]
maxz_levels=[]
for i,row in enumerate(nodes):
    fe=0
    maxz=0
    nodeID,x,y,z=row
    for j,line in enumerate(nodes):
        nodeID2,x2,y2,z2=line
        if x==x2 and y==y2 and z2>maxz:
            maxz=z2
    if len(maxz_levels)==0:
        maxz_levels.append([x, y, maxz])
    else:
        for row2 in maxz_levels:
            if row2[0]==x and row2[1]==y:
                fe=1
        if fe==0:
            maxz_levels.append([x, y, maxz])

但这需要很长时间......所以我想到了使用字典,但我没有找到一种简单的方法来做我想做的事。我的代码是:

dic1=defaultdict(list)             
for nodeID,x,y,z in nodes:
    dic1[(x,y)].append((nodeID,z))
for key in dic1:
    dic1[key].sort( key=lambda x:float(x[1]) )
for j,row in enumerate(nodes):
    nodeID,x,y,z=row
    z_levels=[item[1] for item in dic1[(x,y)]]
    #How to find easily and quickly the max of z_levels and the associated (x,y) coordinates?

有任何想法吗?谢谢

编辑:示例:

nodes = [['1','1','1','2'],['2','1','1','3'],['3','0','0','5'],['4','0','0','4'],['5','1','2','4'],['6','0','0','40'],['7','0','10','4'],['8','10','0','4'],['9','0','0','4'],['10','2','1','4']]

我想找到:

maxz_levels = [[1, 1, 3], [0, 0, 40], [1, 2, 4], [0, 10, 4], [10, 0, 4], [2, 1, 4]]
4

3 回答 3

1
#!/usr/bin/env python3


nodes = [['1','1','1','2'],['2','1','1','3'],['3','0','0','5'],['4','0','0','4']]

d = {}

for z in nodes:
    x = (z[1], z[2])
    if x not in d:
        d[x] = z[3]
    elif d[x] < z[3]:
        d[x] = z[3]

output = []
for x in d:
    output.append(x+(d[x],))
print(output)

输出:

[('0', '0', '5'), ('1', '1', '3')]
于 2013-11-14T19:58:17.620 回答
1

如果您的物品是按您的 X 和 Y 订购的,那么:

from itertools import groupby
from operator import itemgetter

nodes = [['1','1','1','2'],['2','1','1','3'],['3','0','0','5'],['4','0','0','4']]    
result = [max(g, key=itemgetter(3))[1:] for k, g in groupby(nodes, itemgetter(1, 2))]
# [['1', '1', '3'], ['0', '0', '5']]

否则,您可以提供sorted(nodes, key=itemgetter(1, 2))而不是nodesto groupby

于 2013-11-14T20:17:21.910 回答
1
您可以将max函数与键一起使用:
maxz = max(list_, key=lambda x: x[3])
这将分配maxz给列表中list_具有最大值且索引为 3(z 值)的项目。然后,您可以提取 `xi` 和 `yi` 值:
xi, yi = (maxz[1], maxz[2])

如果您想nodes按 z 对列表进行排序,您可以将该sorted函数与key:一起使用
maxz_levels = sorted(nodes, key=lambda x: x[3], reverse=True) ,然后删除第一项。


好吧,我想我终于明白了你的问题。所以这是一个功能性的尝试:

maxz_levels = []
for i in set([(i[1], i[2]) for i in nodes]):
    m = sorted(filter(lambda x: x[1] == i[0] and x[2] == i[1], nodes))[-1]
    maxz_levels.append((m[1], m[2], m[3]))

解释:

  • for循环遍历所有(x, y)组合的列表nodes
  • 循环中的第一行按它们的值nodes对包含当前(x, y)值的所有项目的列表进行排序,z并取最后一个(具有z最大值的那个)。
  • 然后循环中的第二行将此节点添加到最大节点列表中。
于 2013-11-14T18:00:02.200 回答