繁体   English   中英

如何在python中创建排序列表或字典?

[英]How to create a sorted list or dictionary in python?

我想创建一个字符串列表,并且元素按字符串长度排序。 例如:

my_list = ['a', 'bc', 'fef', 'cde', 'xxxx']

当我将元素插入此初始的空my_list时,如何保持这样的顺序? 在Java中,我可以创建一个自定义订单函数并将其作为构造函数参数传递。

我只是发现这是最简单的方法:

l = sorted(my_list, key=str.__len__)

您可以将列表与heapq模块一起使用,以使其保持“已排序” *。

import heapq

my_list = []
for value in ['a', 'bc', 'fef', 'cde', 'xxxx']:
    heapq.heappush(my_list, value)

要提供自定义排序功能,可以使用一个小的包装器:

class Heap(list):
    """
    A lightweight heap essentially utilizing the heapq module.
    It can however be supplied a key argument on initialization. The heap
    itself is a list of tuples of (key, element), but popping is transparent.
    """

    def __init__(self, initial=None, key=lambda x: x):
        """
        Return an empty heap.
        If it has the argument 'initial', it is assumed to be an iterable from
        which the heap will be initialized.
        'key' is a function similar to those usable in the sort() function,
        which will be used whenever a comparison is made.
        """
        self.key = key
        if initial:
            self.extend((key(item), item) for item in initial)
            heapq.heapify(self)

    def push(self, item):
        """Push an element on the heap."""
        heapq.heappush(self, (self.key(item), item))

    def pop(self):
        """Pop the smallest element off the heap, maintaining the invariant."""
        return heapq.heappop(self)[1]

    def replace(self, item):
        """
        Pop an element off the heap, then push.
        More efficient then first popping and then pushing.
        """
        return heapq.heapreplace(self, (self.key(item), item))[1]

    def pushpop(self, item):
        """
        Push an element on the heap, then pop and return the smallest item.
        More efficient then first pushing and then popping.
        """
        return heapq.heappushpop(self, (self.key(item), item))[1]

用法:

>>> my_heap = Heap(['a', 'bc', 'fef', 'cde', 'xxxx'])
>>> my_heap.push('fooooo')

*:堆后面的列表看起来不会排序,但是使用堆接口时它是。

一种可能的解决方案是使用bisect.insortdoc )。 该函数将值插入列表,同时保持排序顺序:

from collections import UserString
from bisect import insort

class custom_string(UserString):
    def __eq__(self, other):
        return len(self) == len(other)

    def __lt__(self, other):
        return len(self) < len(other)


def insert(lst, s):
    insort(my_list, custom_string(s))

my_list = []

insert(my_list, 'cde')
insert(my_list, 'a')
insert(my_list, 'bc')
insert(my_list, 'xxxx')
insert(my_list, 'fef')

print(my_list)

印刷品:

['a', 'bc', 'cde', 'fef', 'xxxx']

编辑: my_list中的custom_string具有自定义__eq____lt__函数的__lt__类型。 要将其重新键入为正常字符串,请使用例如str()

您可以像这样使用SortedList。 您可能需要先安装sortedcontainer才能使用它

from sortedcontainers import SortedList
x=['fef', 'cde', 'xxxx','a', 'bc']
sl = SortedList(x,key=lambda x: len(x))
list(sl) #['a', 'bc', 'fef', 'cde', 'xxxx']

您可以按照帖子中的说明进行排序。 但是,如果要在适当的索引处插入新的传入元素(按适当的含义,插入不应干扰不断增加的“长度”标准),则下面的函数也很简单。 我假设您已经有一个列表my_list = ['a','bc','fef','cde','xxxx'],然后您要从Random_Strings = ['b','ghij ','fgh']。

import numpy as np
my_list = ['a', 'bc', 'fef', 'cde', 'xxxx']
Random_Strings = ['b','ghij','fgh']

def add_string_at_appropriate_index(ListWhereToInsert,StringToInsert):
    Diff_of_Length = np.array([len(x)-len(StringToInsert) for x in ListWhereToInsert])
    AppropriateIndex = np.where(Diff_of_Length==0)[0][0]
    ListWhereToInsert.insert(AppropriateIndex,StringToInsert)
    return ListWhereToInsert

for each_random_string in Random_Strings:
    my_list = add_string_at_appropriate_index(my_list,each_random_string)

print(my_list)    

运行它时,每次插入后都会得到一个已排序的列表。 每次插入后无需排序。 打印输出如下。

['b', 'a', 'bc', 'fgh', 'fef', 'cde', 'ghij', 'xxxx']

这是完成这项工作的另一种方式(如本线程中已经提供的)。 在特定情况下可能对某人有用。 在这种情况下,您已经找到了解决方案,恭喜!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM