有没有一种有效的方法来更改列表中的所有元素,使最小的数字变为零,并且后面的每个数字都有整数间距?
Is there an efficient way to change all the elements in a list such that the lowest number becomes a zero, and each number after has integer spacing?
我一般想实现以下目标,理想情况下不使用 for 循环来遍历每个元素,因为这看起来效率不高。列表的每个元素都将是 int 类型。
3 个示例:
In [1]: L1 = [3,6,19,6,3,3,19]
In [2]: f(L1)
Out [2]: [0,1,2,1,0,0,2]
In [3]: L2 = [0,1,2,4,1,4,1,0]
In [4]: f(L2)
Out [4]: [0,1,2,3,1,3,1,0]
In [5]: L3 = [2,3,3,4,2,2,3,4]
In [6]: f(L3)
Out [6]: [0,1,1,2,0,0,1,2]
数字的顺序并不重要,但相对频率很重要。
如果数字之间没有空格,我目前的尝试是有效的——就像在 L3 中一样。
我的尝试:
def f(L):
L = np.array(L) - min(L)
return list(L)
但这显然没有按照我想要的方式处理差异。如果我可以避免对 L 的每个元素使用 for 循环并且也避免进行元素明智的比较(比如检查 L1 中 19 之后的下一个最小数字是否是 6)那将是理想的,但对我来说并不明显有一种方法可以避免这种情况。
我认为您不可能在 O(n) 时间内完成此操作,因此试图避免 for
遍历列表是没有用的。这是我将采用的方法:
>>> def f(nums):
... m = {num: i for i, num in enumerate(sorted(set(nums)))}
... return [m[num] for num in nums]
...
>>> f([3,6,19,6,3,3,19])
[0, 1, 2, 1, 0, 0, 2]
>>> f([0,1,2,4,1,4,1,0])
[0, 1, 2, 3, 1, 3, 1, 0]
>>> f([2,3,4,4,2,2,3,4])
[0, 1, 2, 2, 0, 0, 1, 2]
请注意,排序是 O(m log m),其中 m 是唯一数字的数量,因此在最坏的情况下这是 O(n log n)。
请注意,如果您实际使用 numpy
开始,则可以将 numpy.unique
与 return_inverse=True
参数一起用于此特定因式分解:
>>> np.unique(L1, return_inverse=True)
(array([ 3, 6, 19]), array([0, 1, 2, 1, 0, 0, 2]))
这应该非常高效,但您应该针对您的特定 use-case 进行分析。请注意,这具有您想要的行为,因为 np.unique
将 return 排序 数组的唯一元素。
我一般想实现以下目标,理想情况下不使用 for 循环来遍历每个元素,因为这看起来效率不高。列表的每个元素都将是 int 类型。
3 个示例:
In [1]: L1 = [3,6,19,6,3,3,19]
In [2]: f(L1)
Out [2]: [0,1,2,1,0,0,2]
In [3]: L2 = [0,1,2,4,1,4,1,0]
In [4]: f(L2)
Out [4]: [0,1,2,3,1,3,1,0]
In [5]: L3 = [2,3,3,4,2,2,3,4]
In [6]: f(L3)
Out [6]: [0,1,1,2,0,0,1,2]
数字的顺序并不重要,但相对频率很重要。
如果数字之间没有空格,我目前的尝试是有效的——就像在 L3 中一样。
我的尝试:
def f(L):
L = np.array(L) - min(L)
return list(L)
但这显然没有按照我想要的方式处理差异。如果我可以避免对 L 的每个元素使用 for 循环并且也避免进行元素明智的比较(比如检查 L1 中 19 之后的下一个最小数字是否是 6)那将是理想的,但对我来说并不明显有一种方法可以避免这种情况。
我认为您不可能在 O(n) 时间内完成此操作,因此试图避免 for
遍历列表是没有用的。这是我将采用的方法:
>>> def f(nums):
... m = {num: i for i, num in enumerate(sorted(set(nums)))}
... return [m[num] for num in nums]
...
>>> f([3,6,19,6,3,3,19])
[0, 1, 2, 1, 0, 0, 2]
>>> f([0,1,2,4,1,4,1,0])
[0, 1, 2, 3, 1, 3, 1, 0]
>>> f([2,3,4,4,2,2,3,4])
[0, 1, 2, 2, 0, 0, 1, 2]
请注意,排序是 O(m log m),其中 m 是唯一数字的数量,因此在最坏的情况下这是 O(n log n)。
请注意,如果您实际使用 numpy
开始,则可以将 numpy.unique
与 return_inverse=True
参数一起用于此特定因式分解:
>>> np.unique(L1, return_inverse=True)
(array([ 3, 6, 19]), array([0, 1, 2, 1, 0, 0, 2]))
这应该非常高效,但您应该针对您的特定 use-case 进行分析。请注意,这具有您想要的行为,因为 np.unique
将 return 排序 数组的唯一元素。