Python:在列表中查找最小数的最长序列的长度时,输出不正确

时间:2018-11-18 12:23:44

标签: python

我正在尝试在列表中找到最小编号的最长序列。例如,对于此列表 resp_rates = [1,1,2,89,56,4,1,1,1,1,10,5,67,1,1,1,76,5,7,6,6,6,1,1,1,1,1,1,1],最小数量为1,且1的序列长度分别为2、4、3、7。因此,最长序列的长度为7,但是我的代码显示为4。

代码:

resp_rates = [1,1,2,89,56,4,1,1,1,1,10,5,67,1,1,1,76,5,7,6,6,6,1,1,1,1,1,1,1]
rr_min_current = np.amin(resp_rates)
print(rr_min_current)
count = 0
first = 1
min_rr_sequence = []
print(resp_rates)
for resp_rate in resp_rates:
    if resp_rate == rr_min_current and first == 1:
        count=count+1 
        first = 0
    elif resp_rate == rr_min_current and first == 0:
        count=count+1
    elif resp_rate != rr_min_current and first == 0:    
        min_rr_sequence.append(count)
        first = 1
        count = 0
#longest_min_rr_sequence.append(np.amax(min_rr_sequence))
print(min_rr_sequence)
longest_min_rr_sequence = np.amax(min_rr_sequence)
print(longest_min_rr_sequence)

输出:

1
[1, 1, 2, 89, 56, 4, 1, 1, 1, 1, 10, 5, 67, 1, 1, 1, 76, 5, 7, 6, 6, 6, 1, 1, 1, 1, 1, 1, 1]
[2, 4, 3]
4

4 个答案:

答案 0 :(得分:2)

使用groupby的简短解决方案:

from itertools import groupby

resp_rates = [1,1,2,89,56,4,1,1,1,1,10,5,67,1,1,1,76,5,7,6,6,6,1,1,1,1,1,1,1]

out = -min((value, -len(list(group))) for value, group in groupby(resp_rates))[1]
print(out)
# 7

一些解释: (value, -len(list(group))) for value, group in groupby(resp_rates))生成元组:(1, -2), (2, -1), (89, -1), ... (1, -4) ...

采用min将返回具有最小值的元组,如果许多具有相同的最小值,则返回具有最大长度的元组(因此,使用-length可以做到这一点加上分钟)。

我们只需要保持最小的元组的长度并更改其符号即可。

答案 1 :(得分:1)

执行以下操作:

In [72]: resp_rates = [1,1,2,89,56,4,1,1,1,1,10,5,67,1,1,1,76,5,7,6,6,6,1,1,1,1,1,1,1]

In [73]: import itertools,operator
In [83]: r = max((list(y) for (x,y) in itertools.groupby((enumerate(resp_rates)),operator.itemgetter(1)) if x == min(resp_rates)), key=len)

In [84]: len(r)
Out[84]: 7

答案 2 :(得分:1)

您在这里(编辑):

resp_rates = [1,1,1,1,1,1,1,1,1,1,1,2,89,56,4,1,1,1,1,10,5,67,1,1,1,76,5,7,6,6,6,1,1,1,1,1,1,1]

lowest = resp_rates[0]
count = 0
max_count = 0

for i in resp_rates:
    if i < lowest:
        lowest = i
        count = 1
        max_count = count
    elif i == lowest:
        count = count + 1
        if count > max_count:
            max_count = count
    else:
        count = 0


print(max_count)

答案 3 :(得分:1)

添加一行 像下面的代码一样,min_rr_sequence.append(count)纠正了所提供代码中的缺陷:

import numpy as np
resp_rates = [1,1,2,89,56,4,1,1,1,1,10,5,67,1,1,1,76,5,7,6,6,6,1,1,1,1,1,1,1]
rr_min_current = np.amin(resp_rates)
print(rr_min_current)
count = 0
first = 1
min_rr_sequence = []
print(resp_rates)
for resp_rate in resp_rates:
    if resp_rate == rr_min_current and first == 1:
        count=count+1 
        first = 0
    elif resp_rate == rr_min_current and first == 0:
        count=count+1
    elif resp_rate != rr_min_current and first == 0:    
        min_rr_sequence.append(count)
        first = 1
        count = 0
min_rr_sequence.append(count)

问题在于,如果最长计数的序列发生在.append(count)列表的末尾,则提供的代码未运行resp_rates

正如Thierry Lathuille在对问题的评论中所指出的那样,代码中的缺陷是“不会到达添加了序列数的最后一个省略号”。

值得注意的事实是,Thierry Lathuille的itertools.groupby(),min()和len()提供的解决方案是其他提供的解决方案的将近10倍(状态:11月18日, 2018,17:30 MEZ)来完成此任务。

在系统上自行检查。这里的代码:

import time
# resp_rates = [1,1,2,89,56,4,1,1,1,1,10,5,67,1,1,1,76,5,7,6,6,6,1,1,1,1,1,1,1]
# resp_rates = [1,1,1,1,1,1,1,1,1,2,89,56,4,1,1,1,1,10,5,67,1,1,1,76,5,7,6,6,6,1,1,1,1,1,1,1]
# resp_rates = [1,1,1,1,1,1,1,1,1,1,1,2,89,56,4,1,1,1,1,10,5,67,1,1,1,76,5,7,6,6,6,1,1,1,1,1,1,1]
# resp_rates = [1,1,2,89,56,4,1,1,1,1,10,5,67,1,1,1,76,5,7,6,6,6,1,1,1]
# resp_rates = [5,1,1,2,89,56,4,1,1,1,1,10,5,67,1,1,1,76,5,7,6,6,6,1,1,1,1,1,1,1]
# resp_rates = [1,3,1,1,1,2,1,1,4,1,1,1,1]
resp_rates = [7,7,7,7,7,7,7,8,8,8,8,8,8,8,8]

# -----------------------------------------------------------------------------
print("# Original code with one line added to make it print correct result:")
import numpy as np

largeList = 20000000*[5]
resp_rates = resp_rates + largeList 

timeNOW = time.time()
rr_min_current = np.amin(resp_rates)
# print(rr_min_current)
count = 0
first = 1
min_rr_sequence = []
# print(resp_rates)
for resp_rate in resp_rates:
    if resp_rate == rr_min_current and first == 1:
        count=count+1 
        first = 0
    elif resp_rate == rr_min_current and first == 0:
        count=count+1
    elif resp_rate != rr_min_current and first == 0:    
        min_rr_sequence.append(count)
        first = 1
        count = 0
min_rr_sequence.append(count)

#longest_min_rr_sequence.append(np.amax(min_rr_sequence))
# print(min_rr_sequence)
longest_min_rr_sequence = np.amax(min_rr_sequence)
print("Result of timing", time.time() - timeNOW )
print(longest_min_rr_sequence)

# -----------------------------------------------------------------------------
print("# Provided solution using itertools.groupby(), min() and len(): ")
timeNOW = time.time()
from itertools import groupby
out = -min((value, -len(list(group))) for value, group in groupby(resp_rates))[1]
print("Result of timing", time.time() - timeNOW )
print(out)
# 7

# -----------------------------------------------------------------------------
print("# Provided solution using itertools.groupby() and operator.itemgetter(): ")
timeNOW = time.time()
import itertools, operator
r = max((list(y) for (x,y) in itertools.groupby((enumerate(resp_rates)),operator.itemgetter(1)) if x == min(resp_rates)), key=len)
print("Result of timing", time.time() - timeNOW )
print(len(r))


print("# Accepted answer: ")
timeNOW = time.time()
lowest = resp_rates[0]
count = 0
max_count = 0
for i in resp_rates:
    if i < lowest:
        lowest = i
        count = 1
    elif i == lowest:
        count = count + 1
    else:
        if count != 0:
            max_count = count
        count = 0

if count != 0:
    max_count = count

print("Result of timing", time.time() - timeNOW )
print(max_count)

print("# Accepted answer (EDITED): ")
timeNOW = time.time()

lowest = resp_rates[0]
count = 0
max_count = 0

for i in resp_rates:
    if i < lowest:
        lowest = i
        count = 1
        max_count = count
    elif i == lowest:
        count = count + 1
        if count > max_count:
            max_count = count
    else:
        count = 0
print("Result of timing", time.time() - timeNOW )
print(max_count)

这是我系统上的打印输出:

python3.6 -u "longestSequence-ofMinimalNumber_Cg.py"
# Original code with one line added to make it print correct result:
Result of timing 10.655358791351318
20000000
# Provided solution using itertools.groupby(), min() and len(): 
Result of timing 0.3956716060638428
20000000
# Provided solution using itertools.groupby() and operator.itemgetter(): 
Result of timing 4.829622983932495
20000000
# Accepted answer: 
Result of timing 3.7705492973327637
20000000
# Accepted answer (EDITED): 
Result of timing 5.475024223327637
20000000