Python如何按第一个和第二个键值对字典排序?

2024-05-23 15:54:20 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在处理一个文本文件“biones.txt”。其内容示例如下所示:

Special Type A Sunflower
2016-10-12 18:10:40
Asteraceae
Ingredient in Sunflower Oil
Brought to North America by Europeans
Requires fertile and moist soil
Full sun

Pine Tree
2018-12-15 13:30:45
Pinaceae
Evergreen
Tall and long-lived
Temperate climate

Tropical Sealion
2019-01-20 12:10:05
Otariidae
Found in zoos
Likes fish
Likes balls
Likes zookeepers

Big Honey Badger
2020-06-06 10:10:25
Mustelidae
Eats anything
King of the desert

当它的内容转换为字典输入的值时,它运行良好。
输入

def TextFileToDictionary():
    dataset = [] 
    with open(FinalFilePath, "r") as textfile:  
        sections = textfile.read().split("\n\n")
        for section in sections:                 
            lines = section.split("\n")      
            dataset.append({                
              "Name": lines[0],                 
              "Date": lines[1],              
              "Information": lines[2:]          
            })
        return dataset                          
TextFileToDictionary()


输出

[{'Name': 'Special Type A Sunflower',
  'Date': '2016-10-12 18:10:40',
  'Information': ['Asteraceae',
   'Ingredient in Sunflower Oil',
   'Brought to North America by Europeans',
   'Requires fertile and moist soil',
   'Full sun']},
 {'Name': 'Pine Tree',
  'Date': '2018-12-15 13:30:45',
  'Information': ['Pinaceae',
   'Evergreen',
   'Tall and long-lived',
   'Temperate climate']},
 {'Name': 'Tropical Sealion',
  'Date': '2019-01-20 12:10:05',
  'Information': ['Otariidae',
   'Found in zoos',
   'Likes fish',
   'Likes balls',
   'Likes zookeepers']},
 {'Name': 'Big Honey Badger',
  'Date': '2020-06-06 10:10:25',
  'Information': ['Mustelidae', 'Eats anything', 'King of the desert']}]

正如所观察到的,输出包含多个字典,没有名称

目前,我正在尝试创建一些函数,这些函数将按照
1)第一个键值(按字母顺序)和
2)第二个键值(按最新日期)对字典进行排序

我的进展情况如下:

import itertools
import os

MyFilePath = os.getcwd() 
ActualFile = "creatures.txt"
FinalFilePath = os.path.join(MyFilePath, ActualFile) 

def TextFileToDictionaryName():
    dataset = [] 
    with open(FinalFilePath, "r") as textfile:  
        sections = textfile.read().split("\n\n")
        for section in sections:                 
            lines = section.split("\n")      
            dataset.append({                
              "Name": lines[0],                 
              "Date": lines[1],              
              "Information": lines[2:]          
            })
            dataset.sort(key=lambda x: x[0]['Name'], reverse=False)
        return dataset                          
TextFileToDictionaryName()

def TextFileToDictionaryDate():
    dataset = [] 
    with open(FinalFilePath, "r") as textfile:  
        sections = textfile.read().split("\n\n")
        for section in sections:                 
            lines = section.split("\n")      
            dataset.append({                
              "Name": lines[0],                 
              "Date": lines[1],              
              "Information": lines[2:]          
            })
            dataset.sort(key=lambda x: x[1]['Date'], reverse=True)
        return dataset                          
TextFileToDictionaryDate()

但是,我遇到了一个错误“KeyError:0”。我不知道如何解决它。
我也不确定如何将字典输出转换回字符串格式,就像前面的“bioters.txt”文件的内容一样

有人知道如何修复代码吗

非常感谢


Tags: andnameindate字典informationsectiondataset
3条回答

不要使用dict。您的数据似乎有相应的模型

相反,创建一个适当的Python class,一个Creature

class Creature:
    __init__(self, name, date, habitat):
        self.name = name
        self.date = date
        self.habitat = habitat
        # etc.

在读取输入文件时,为每个数据分组创建新的Creature实例。将每个Creature添加到某种集合中:

creatures = list()
with open(FinalFilePath, "r") as textfile:  
    sections = textfile.read().split("\n\n")
    for section in sections:                 
        lines = section.split("\n")      
        creatures.append(Creature(lines[0], lines[1])) # add more params?

下一步,add some boiler-plate methods (^{}, etc.)Creature类,这样它就可以排序了

最后,只需使用sorted(creatures),然后您的生物集合将根据__lt__逻辑进行排序

__lt__的实现如下所示:

def __lt__(self, other):
    if self.name < other.name:
        return True
    elif self.name > other.name:
        return False
    elif self.date < other.date:
        return True
    elif self.date > other.date:
        return False
    else
        # What happens if name and date are the same?

**或者,您可以使用creatures = SortedList(),然后在调用creates.add(Creature(...))时将每个项插入到正确的位置。最后不需要sorted(creatures)调用

您不需要先按姓名再按日期对列表进行单独排序。你可以同时做这两件事。

获取KeyError的原因:key参数用于指定在进行比较之前对每个列表元素调用的函数。元素x将是一个字典而不是一个列表,因此我希望您使用x[0]的原因是您假定x是一个列表,但它不是

from datetime import datetime

sample = [
    {
        "Name": "Special Type A Sunflower",
        "Date": "2016-10-12 18:10:40",
        "Information": [...],
    },
    {
        "Name": "Pine Tree",
        "Date": "2018-12-15 13:30:45",
        "Information": [...],
    },
    {
        "Name": "Tropical Sealion",
        "Date": "2019-01-20 12:10:05",
        "Information": [...],
    },
    {
        "Name": "Big Honey Badger",
        "Date": "2020-06-06 10:10:25",
        "Information": [...],
    },
]

sample.sort(
    key=lambda x: (x["Name"], datetime.strptime(x["Date"], "%Y-%m-%d %H:%M:%S"))
)

你就快到了,只是不要做x[0]x[1]。 另外,我认为您不应该在循环的每次迭代中对列表进行排序,而应该只在循环的最后进行排序

def TextFileToDictionaryName():
    dataset = [] 
    with open(FinalFilePath, "r") as textfile:  
        sections = textfile.read().split("\n\n")
        for section in sections:                 
            lines = section.split("\n")      
            dataset.append({                
              "Name": lines[0],                 
              "Date": lines[1],              
              "Information": lines[2:]          
            })
        dataset.sort(key=lambda x: x['Name'], reverse=False)
        return dataset                          
TextFileToDictionaryName()

def TextFileToDictionaryDate():
    dataset = [] 
    with open(FinalFilePath, "r") as textfile:  
        sections = textfile.read().split("\n\n")
        for section in sections:                 
            lines = section.split("\n")      
            dataset.append({                
              "Name": lines[0],                 
              "Date": lines[1],              
              "Information": lines[2:]          
            })
        dataset.sort(key=lambda x: x['Date'], reverse=True)
        return dataset                          
TextFileToDictionaryDate()

相关问题 更多 >