这是应该,根据他们执行的任务数量(他们在输入列表中出现了多少次),以及如果有2名参赛者具有相同数量的任务,然后按时间排序(最小到最大)。
例如,给定此
["tyson 0:11", "usain 0:12", "carl 0:30", "carl 0:20", "usain 0:40", "carl 1:00", "usain 0:57"]
作为输入,应该返回以下内容:
["usain", "carl", "tyson"]
但是,在按任务排序之后,我似乎无法弄清楚如何按时间排序。
代码:
from more_itertools import unique_everseen
def winners(data):
names = []
times = []
taskcount = []
ndict = {}
for i in data:
name = i.split()[0]
time = i.split()[1]
numMin, numSec = time.split(':')
nmin = int(numMin)
nsec = int(numSec)
total = (60 * nmin) + nsec
names.append(name)
times.append(total)
index = 0
for name in names:
count = names.count(name)
taskcount.append(count)
for name in names:
taskcount.pop(0)
taskcount = list(unique_everseen(taskcount))
for name in names:
if name not in ndict:
ndict[name] = [taskcount[index], times[index]]
else:
ndict[name][1] += times[index]
index += 1
sortedDict = sorted(ndict.items(),reverse = True , key=lambda kv: kv[1])
R = [t[0] for t in sortedDict]
return R
最重要的是,每当我输入某个列表时,它看起来都可以正常工作,但当我输入其他列表时,它就爆炸了:
Traceback (most recent call last):
File "<ipython-input-69-420jihgfedcc>", line 1, in <module>
runfile('C:/Users/User/Folder/contestWinner.py', wdir='C:/Users/User/Folder')
File "C:\Users\User\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 704, in runfile
execfile(filename, namespace)
File "C:\Users\User\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 108, in execfile
exec(compile(f.read(), filename, 'exec'), namespace)
File "C:/Users/User/Folder/contestWinner.py", line 42, in <module>
print(winners(data))
File "C:/Users/User/Folder/contestWinner.py", line 33, in winners
ndict[name] = [taskcount[index], times[index]]
IndexError: list index out of range
反正有没有解决错误和按时间排序的方法?抱歉,如果这真的很愚蠢,我是Python的初学者。
答案 0 :(得分:1)
另一个答案已解决了该问题,但我想提出一种更实用的方法:
data = ["tyson 0:11", "usain 0:12", "carl 0:30", "carl 0:20", "usain 0:40", "carl 1:00", "usain 0:57"]
from itertools import groupby
from operator import itemgetter
def process_time(t):
minutes, seconds = map(int, t.split(':'))
return 60 * minutes + seconds
def sort_key(pair):
return (-len(pair[1]), min(pair[1]))
grouped = groupby(sorted(task.split() for task in data),
key=itemgetter(0))
processed = {key: [process_time(time) for name, time in group]
for key, group in grouped}
print(processed)
print([name for name, time in sorted(processed.items(), key=sort_key)])
输出:
{'carl': [20, 30, 60], 'tyson': [11], 'usain': [12, 40, 57]}
['usain', 'carl', 'tyson']
首先,我们使用sorted
和itertools.groupby
按第一个元素对输入数据中的每个条目进行排序和分组。这样一来,我们就可以以dict
的结构化形式获取数据,其中键是名称,值是lists
倍。
一路走来,我们还将表示时间的字符串处理为以秒为单位的整数。
接下来,我们要按dict
的键值对它们进行排序,首先按长度的降序(因为值的长度是任务数),然后按最小时间的升序进行排序。
这是通过指定键函数sort_key
来完成的,该键函数在此返回一个tuple
。按键功能的作用是对输入进行排序,就像对按键应用了一样。
tuples
按其第一个元素排序,然后按第二个元素排序,依此类推,直到打破所有联系或到达最后一个元素为止。在这种情况下,我们有一个2元组,其中第一个元素是输入的负长度,第二个元素是最小值。
请注意,前者是负数,因为默认情况下sorted
以升顺序排序;通过忽略长度,我们可以颠倒排序顺序。在仅对一个元素进行排序的情况下,您可以传递reverse=True
,但是在这里,我们可以按不同的顺序进行两种排序。
所有这些的结果是我们执行了必要的排序才能得到答案。
答案 1 :(得分:0)
由于以下几行而出现此错误:
for name in names:
taskcount.pop(0)
taskcount = list(unique_everseen(taskcount))
删除这些内容也会删除错误。
但是,您的代码仍不会返回您期望的顺序,因为它将更多的时间放在首位。您会在末尾或返回[('carl', [3, 110]), ('usain', [3, 109]), ('tyson', [1, 11])]
时得到['carl', 'usain', 'tyson']
,因为卡尔的总时间比美国长。
应该只对sortedDict = sorted(ndict.items(),reverse = True , key=lambda kv: kv[1])
行进行调整,以便按时间在相反的方向上进行排序。
答案 2 :(得分:0)
from collections import Counter
data_release = ["tyson 0:11", "usain 0:12", "carl 0:30", "carl 0:20", "usain 0:40", "carl 1:00", "usain 0:57"]
def sorted_data(data):
temp_data = []
for item in data:
item = item.split()[0]
temp_data.append(item)
temp_dict = dict(Counter(temp_data))
sorted_list = sorted(temp_dict.items(), key=lambda d: - d[1])
result = []
for temp_tuple in sorted_list:
result.append(temp_tuple[0])
return result
print(sorted_data(data_release))
充分利用python集合库,问题会更加简单!
答案 3 :(得分:0)
我通过稍微修改gmds的代码解决了这个问题,所以我将接受他/她的代码。我使用了一个简单的嵌套for循环,用原始值中组合时间的列表替换了processed
的每个值。谢谢gmds!
代码:
from itertools import groupby
from operator import itemgetter
def winners(data):
def process_time(t):
minutes, seconds = map(int, t.split(':'))
return 60 * minutes + seconds
def sort_key(pair):
return (-len(pair[1]), min(pair[1]))
grouped = groupby(sorted(task.split() for task in data), key=itemgetter(0))
processed = {key: [process_time(time) for name, time in group]
for key, group in grouped}
for name in list(processed.keys()):
length = len(processed.get(name))
value = []
for i in range(length):
value.append(sum(processed.get(name)))
processed[name] = value
sortedL = [name for name, time in sorted(processed.items(), key = sort_key)]
return sortedL
if __name__ == "__main__":
data = ["owen 2:00", "jeff 1:29", "owen 1:00", "jeff 1:30", "robert 0:21"]
print(winners(data))
感谢帮助人员!