我遇到了一些我无法找到解决方案的问题。
我有一个看起来像他的名单,实际上有60000个元素:
lst = [[0, [-24.75, -24.75, -25.0], 0.00001, 2],
[10, [-26, -26, -26], 0.00011, 4],
[0, [-3, -200000, -25.0], 0.000009, 42],
[0, [-4, -4.7, -5], 0.00801, 7],
[1, [-3, -200000, -25.0], 0.00089, 8],
[2, [-3, -200000, -25.0], 0.000899, 18]]
元素[lst[i][1] for i in range(len(lst))]
应该是笛卡尔坐标,其中一些不止一次出现。
我想给每个坐标一个唯一的编号,以便列表变为:
lst = [[0, 0, 0.00001, 2],
[10, 1, 0.00011, 4],
[0, 2, 0.000009, 42],
[0, 3, 0.00801, 7],
[1, 2, 0.00089, 8],
[2, 2, 0.000899, 18]]
这意味着,如果坐标[-3, -200000, -25.0]
曾被数字(此处为2
)替换,则此坐标的所有重复项也必须替换为相同的数字。
如果原始列表lst
中的元素将被重新排列也是可以的,主要的是我需要用数字替换所有坐标三元组。
提前谢谢。
答案 0 :(得分:2)
我们可以先构建一个defaultdict
:
from collections import defaultdict
from itertools import count
dispatcher = defaultdict(lambda c=count(0): next(c))
现在我们可以简单地用查找代替。现在由于元素不可清除,我们不能简单地将它们添加到字典中。但我们可以将它们转换为元组。
现在我们可以使用:
for lsti in lst:
lsti[1] = dispatcher[tuple(lsti[1])]
对于给定的输入,这会生成:
>>> lst
[[0, 0, 1e-05, 2], [10, 1, 0.00011, 4], [0, 2, 9e-06, 42], [0, 3, 0.00801, 7], [1, 2, 0.00089, 8], [2, 2, 0.000899, 18]]
答案 1 :(得分:2)
制作您已经看过的价值字典。对于列表中的每个项目,如果其坐标位于该字典中,请使用其保存的值。否则,将该密钥插入字典并更新运行计数:
coordmap = {}
count = 0
for item in lst:
coords = tuple(item[1])
try:
new_value = coordmap[coords]
except KeyError:
new_value = coordmap[coords] = count
count += 1
item[1] = new_value
答案 2 :(得分:1)
元组是可以清洗的。您可以使用它来轻松维护已访问坐标的字典。
import random
seen = { }
i = 0
for l in lst:
coord = tuple(l[1])
if coord not in seen:
seen[coord] = i
i += 1
l[1] = seen[coord]
内容:
[[0, 0, 1e-05, 2],
[10, 1, 0.00011, 4],
[0, 2, 9e-06, 42],
[0, 3, 0.00801, 7],
[1, 4, 0.00089, 8],
[2, 5, 0.000899, 18]]