我有一个清单:
x = ['c', 'a', 'e']
我可以对此列表进行排序:
x_sorted = sorted(x)
x_sorted
现在是['a', 'c', 'e']
现在假设我有一个新变量y = 'd'
我想知道x_sorted
这个新变量会落在哪里。在此示例中,新变量y
包含字符串'd'
,因此它将作为['a', 'c', 'd', 'e']
放置在列表的索引2中。我希望尽可能有效地找出这个索引号(因为我必须多次重复这个过程)。
这是我写的一个非常简单的任务:
def f(x_sorted, y):
new_list = x_sorted[:] + [y]
return sorted(new_list).index(y)
这给了我正确的答案。
我想知道是否有更好的更有效的方法,因为f
将被称为100,000次以上。
提前致谢!
答案 0 :(得分:9)
您可以使用bisect
from bisect import bisect
l = ['a', 'c', 'e']
print(bisect(l,"d"))
2
将其添加到列表中:
from bisect import insort
l = ['a',"b", 'c', 'e']
insort(l, "d")
print(l)
insort(l, "f")
print(l)
['a', 'b', 'c', 'd', 'e']
['a', 'b', 'c', 'd', 'e', 'f']
如果您想要更快的插入,可以使用blist维护带有insort的排序列表:
O(log**2 n) vs O(n)
来自bisect import insort的
from blist import blist
b = blist(["a", "b", "c", "e"])
insort(b, "f")
insort(b, "d")
print(b)
blist(['a', 'b', 'c', 'd', 'e', 'f'])
还有一个blist.sortedlist列表,您可以使用.add:
from blist import sortedlist
l = ['b',"a", 'c', 'e']
b = sortedlist(l)
b.add("f")
print(b)
sortedlist(['a', 'b', 'c', 'e', 'f'])
还有一个sortedcontainers库,其sortedlist实施。
答案 1 :(得分:2)
如果O(n logn)
没有更改或不经常更改,您可以对其进行预排序,然后在排序列表中使用二进制搜索。对于每次后续查找,这将导致O(logn)
每种加x
费用加上>>> x = ['c', 'a', 'e']
>>> y = 'd'
>>> sum(y > el for el in x)
2
。
如果O(n)
发生了很大变化,您可以使用线性搜索:
#!/bin/bash
# Peter Black
# alarm.sh
max_percent=94
sleeper=1
frequency=1000
duration=300
# To enable the script:
# chmod u+x alert.sh
# get the total available memory:
function total_memory {
echo "Total memory available: "
TOTAL_MEM=$(grep MemTotal /proc/meminfo | awk '{print $2}')
#Another way of doing that:
#total_mem=$(awk '/MemTotal/ {print $2}' /proc/meminfo)
echo "---------- $TOTAL_MEM ---------------"
}
# alarm function params: frequency, duration
# Example:
# _alarm 400 200
_alarm() {
( \speaker-test --frequency $1 --test sine )&
pid=$!
\sleep 0.${2}s
\kill -9 $pid
}
function total_available_memory {
total_available_mem=$(</proc/meminfo grep MemTotal | grep -Eo '[0-9]+')
total_free_mem=$(</proc/meminfo grep MemFree | grep -Eo '[0-9]+')
total_used_mem=$((total_available_mem - total_free_mem))
#percent_used=$((total_available_mem / total_free_mem))
# print the free memory
# customize the unit based on the format of your /proc/meminfo
percent_used=$(printf '%i %i' $total_used_mem $total_available_mem | awk '{ pc=100*$1/$2; i=int(pc); print (pc-i<0.5)?i:i+1 }')
if [ $percent_used -gt $max_percent ]; then
echo "TOO MUCH MEMORY IS BEIGN USED!!!!!!!! KILL IT!"
_alarm $frequency $duration
fi
echo "Available: $total_available_mem kb - Used: $total_used_mem kb - Free: $total_free_mem kb - Percent Used: $percent_used %"
}
# RUN THE FUNCTIONS IN AN INFINITE LOOP:
# total_memory
echo "Press [CTRL+C] to stop.."
while :
do
total_available_memory
sleep $sleeper
done
这具有if (date1.getTime() <= date.getTime() && date.getTime() <= date2.getTime()) {
/*
* date is between date1 and date2 (both inclusive)
*/
}
/*
* when date1 = 2015-01-01 and date2 = 2015-01-10 then
* returns true for:
* 2015-01-01
* 2015-01-01 00:00:01
* 2015-01-02
* 2015-01-10
* returns false for:
* 2014-12-31 23:59:59
* 2015-01-10 00:00:01
*
* if one or both dates are exclusive then change <= to <
*/
查找复杂性。
答案 2 :(得分:0)
这肯定不是你在问题中证明的有效方式,在这种情况下你每次都要对它进行排序,因此如果你执行这个动作m
次,复杂性将是O(m*n*log(m))
,所以首选方法是对其进行一次排序,然后简单地遍历列表以查找索引,这可以在O(n)
中完成,但最好的方法是使用二进制搜索,现在您的时间复杂度将降至O(log(n))
。对于这类问题,这是最小的复杂性。