首页 > 解决方案 > 使用 cmp_to_key 按时间排序

问题描述

每当添加新项目时,我都会尝试按时间订购我的 csvfile 食品。我找到了一个我非常喜欢的解决方案,每次都相互比较。我唯一的问题是我不确定应该将什么变量/数据结构放入标有times.

应该发生的是,新行被添加到 2D 列表 myRows 中,然后 myRows 的内容根据时间进行排序。顺序应该最早在开始,最晚在结束。

    myRows = []
    with open("dataset.txt") as csvfile:
        reader = csv.reader(csvfile)
        for row in reader:
            myRows.append(row)
        newRow = [time, myType, desc, serving, kcal, sfat]
        myRows.append(newRow)
        myRows = sorted(times, key=cmp_to_key(compareTimes))

比较时间功能

def compareTimes(timeStr1,timeStr2):
    #Convert the time Strings passed into function into time objects
    time1 = time.strptime(timeStr1, timeFormat)
    time2 = time.strptime(timeStr2, timeFormat)
    if time1 < time2:
        return -1
    elif time > time2:
        return 1
    else:
        #If times are the same
        return 0

数据集.txt

22:30, Snack, Cereal, 200, 210,1.6
08:11, Breakfast, Cereal, 200, 210,1.6
08:20, Breakfast, Coffee, 200, 20,0.4
08:20, Breakfast, Pancake, 38, 74,1.4
10:30, Snack, Chocolate, 10, 56,2.5

我已经尝试过myRows[0]myRows等等但是这没有奏效。

标签: pythonsortingtime

解决方案


你必须使用myRows作为参数sorted()

myRows = sorted(myRows ...)

但是要对字符串进行排序22:3008:11不需要将字符串转换为的函数,datetime因为您可以比较"22:30" < "08:11". 所以你可以使用

myRows = sorted(myRows, key=lambda x:x[0])

text = '''22:30, Snack, Cereal, 200, 210,1.6
08:11, Breakfast, Cereal, 200, 210,1.6
08:20, Breakfast, Coffee, 200, 20,0.4
08:20, Breakfast, Pancake, 38, 74,1.4
10:30, Snack, Chocolate, 10, 56,2.5'''

import csv
import io

myRows = []
#with open("dataset.txt") as csvfile:
with io.StringIO(text) as csvfile:
    reader = csv.reader(csvfile)
    for row in reader:
        myRows.append(row)
    #newRow = [time, myType, desc, serving, kcal, sfat]
    #myRows.append(newRow)
    myRows = sorted(myRows, key=lambda x:x[0])

for row in myRows:
    print(row)

结果

['08:11', ' Breakfast', ' Cereal', ' 200', ' 210', '1.6']
['08:20', ' Breakfast', ' Coffee', ' 200', ' 20', '0.4']
['08:20', ' Breakfast', ' Pancake', ' 38', ' 74', '1.4']
['10:30', ' Snack', ' Chocolate', ' 10', ' 56', '2.5']
['22:30', ' Snack', ' Cereal', ' 200', ' 210', '1.6']

编辑:相同pandas的要短得多

text = '''22:30, Snack, Cereal, 200, 210,1.6
08:11, Breakfast, Cereal, 200, 210,1.6
08:20, Breakfast, Coffee, 200, 20,0.4
08:20, Breakfast, Pancake, 38, 74,1.4
10:30, Snack, Chocolate, 10, 56,2.5'''

import pandas as pd
import io

#myRows = pd.read_csv("dataset.txt", sep=', ', names=['time', 'myType', 'desc', 'serving', 'kcal', 'sfat'])

myRows = pd.read_csv(io.StringIO(text), sep=', ', names=['time', 'myType', 'desc', 'serving', 'kcal', 'sfat'])

myRows = myRows.sort_values('time')

print(myRows)

编辑:具有功能的版本

text = '''22:30, Snack, Cereal, 200, 210,1.6
08:11, Breakfast, Cereal, 200, 210,1.6
08:20, Breakfast, Coffee, 200, 20,0.4
08:20, Breakfast, Pancake, 38, 74,1.4
10:30, Snack, Chocolate, 10, 56,2.5'''

import csv
from functools import cmp_to_key
import time
import io

def compare_times(row1, row2): # 'lower_case_names' for functions
    #time1 = time.strptime(row1[0], '%H:%M') # converting to time object
    #time2 = time.strptime(row2[0], '%H:%M') # converting to time object
    time1 = row1[0] # without converting to time object
    time2 = row2[0] # without converting to time object

    if time1 < time2:
        return -1
    elif time1 > time2:
        return 1
    else:
        return 0

myRows = []

#with open("dataset.txt") as csvfile:
with io.StringIO(text) as csvfile:
    reader = csv.reader(csvfile)
    for row in reader:
        myRows.append(row)
    #newRow = [time, myType, desc, serving, kcal, sfat]
    #myRows.append(newRow)
    myRows = sorted(myRows, key=cmp_to_key(compare_times))

for row in myRows:
    print(row)

推荐阅读