我有一个清单。
我需要在列表中添加一个单词,但我不知道该怎么做。
例如,
我有一个list = ['Alice', 'Amy', 'Andy', 'Betty', 'Eric', 'Peter', 'Richard', 'Tony']
答案 0 :(得分:4)
您可以使用sortedcontainers
等专家库,每次插入后效率高于幼稚list.sort
。 SortedList.add
的复杂性为~O(log n )。
from sortedcontainers import SortedList
lst = SortedList(['Alice', 'Amy', 'Andy', 'Betty', 'Eric', 'Peter', 'Richard', 'Tony'])
lst.add('Beatrice')
print(lst)
SortedList(['Alice', 'Amy', 'Andy', 'Beatrice', 'Betty', 'Eric', 'Peter', 'Richard', 'Tony'])
答案 1 :(得分:3)
如果你确定你有一个排序列表,你可以实现一个天真的插入排序
def insertion_sort(lst, newval, key=None):
"""insertion_sort(lst, newval) modifies the pre-sorted lst by inserting
newval in its sorted order
"""
if key is None:
key = type(lst[0]).__lt__
for i, val = enumerate(lst):
if key(val, newval):
continue
else:
# newval is less than val, so we insert here
lst.insert(i, newval)
或者你可以,不那么天真地使用stdlib bisect
模块为你插入。
import bisect
l = ['Alice', 'Amy', 'Andy', 'Betty', 'Eric', 'Peter', 'Richard', 'Tony']
bisect.insort(l, "Andrew") # or insort_left
答案 2 :(得分:1)
试试这个:
>>> l = ['Alice', 'Amy', 'Andy', 'Betty', 'Eric', 'Peter', 'Richard', 'Tony']
>>> l.append('Beatrice')
>>> l.sort()
>>> l
['Alice', 'Amy', 'Andy', 'Beatrice', 'Betty', 'Eric', 'Peter', 'Richard', 'Tony']
>>>
答案 3 :(得分:1)
首先,要在两个字符串之间“检查匹配字母”,您真正需要的只是<
。字符串按字典顺序进行比较:'abc' < 'abd' < 'acd' < 'acdd'
。
使用链接列表,您必须从头部搜索节点以查找位置。随时跟踪上一个节点和下一个节点,一旦找到next.head > value
,请在prev
之后插入新节点。 (如果您正在使用裸节点实现,请确保您的函数返回头部 - 否则,无法在头部之前插入。)
当然,这自动意味着找到正确位置的线性时间(如果你使用不可变节点,也需要线性时间来构建新节点,直到头部)。
鉴于您的实施,这可能看起来像SingleLinkedList
上的这些方法:
def find_pos(self, element):
'''Returns the position before element, or None if no such position'''
prev, node = None, self._head
while node:
if node.element > element:
return prev
prev, node = node, node.next
return prev
def insert(self, element):
pos = self.find_pos(element)
if pos:
# add it after the node we found
node = Node(element, pos.next)
pos.next = node
else:
# add it before the current head
node = Node(element, self._head)
self._head = node
self._size += 1
使用像数组(Python list
)这样的随机访问数据结构,您可以bisect
在日志时间中找到正确的位置。但是对于数组,您仍需要线性时间来执行插入操作,因为所有后续值都必须向上移动。 (虽然这通常是线性的,其常数比链表搜索快得多。)
bisect.insort(lst, value)
最后一件事:如果您连续进行大量插入操作,那么批量处理它们通常会更有效。事实上,如果要添加的元素数量是列表中相当大的一部分,那么只调用extend
然后调用sort
实际上可能比insort
更快。{/ p>
如果您想要充分利用这两个方面,您需要一个更复杂的数据结构:
常用的实施包括blist.sortedlist
,sortedcontainers.SortedList
,pybst.AVLTree
等。
但实际上,你在Python中找到的任何这种结构的几乎所有实现都会内置这种行为。所以正确的答案可能就是这样:
lst.add(val)
答案 4 :(得分:0)
使用二叉树,可以在O(height_of_tree)
:
class Tree:
def __init__(self, value = None):
self.right, self.left, self.value = None, None, value
def __lt__(self, _node):
return self.value < getattr(_node, 'value', _node)
def insert_val(self, _val):
if self.value is None:
self.value = _val
else:
if _val < self.value:
if self.left is None:
self.left = Tree(_val)
else:
self.left.insert_val(_val)
else:
if self.right is None:
self.right = Tree(_val)
else:
self.right.insert_val(_val)
def flatten(self):
return [*getattr(self.left, 'flatten', lambda :[])(), self.value, *getattr(self.right, 'flatten', lambda :[])()]
t = Tree()
l = ['Alice', 'Amy', 'Andy', 'Betty', 'Eric', 'Peter', 'Richard', 'Tony']
for i in l:
t.insert_val(l)
t.insert_val('Beatrice')
print(t.flatten())
输出:
['Alice', 'Amy', 'Andy', 'Beatrice', 'Betty', 'Eric', 'Peter', 'Richard', 'Tony']
使用链接列表,您可以在单个方法中执行add
和insert
操作,并应用其他逻辑:
class LinkedList:
def __init__(self, value=None):
self.value = value
self._next = None
def __lt__(self, _node):
return True if self._next is None else _node[0] > self._next.value[0]
def insert_val(self, _val):
if self.value is None:
self.value = _val
else:
if self._next is None or self._next < _val:
getattr(self._next, 'insert_val', lambda x:setattr(self, '_next', LinkedList(x)))(_val)
else:
_temp_next = self._next._next
self._next._next = LinkedList(_val)
self._next._next._next = _temp_next
def flatten(self):
return [self.value, *getattr(self._next, 'flatten', lambda :[])()]
@classmethod
def load_list(cls):
_l = cls()
for i in ['Alice', 'Amy', 'Andy', 'Betty', 'Eric', 'Peter', 'Richard', 'Tony']:
_l.insert_val(i)
return _l
l = LinkedList.load_list()
print(l.flatten())
>>>['Alice', 'Amy', 'Andy', 'Betty', 'Eric', 'Peter', 'Richard', 'Tony']
l.insert_val('Beatrice')
print(l.flatten())
>>>['Alice', 'Amy', 'Andy', 'Beatrice', 'Betty', 'Eric', 'Peter', 'Richard', 'Tony']
答案 5 :(得分:0)
在 bisect 模块提供了对按列表顺序维护列表的支持 必须在每次插入后对列表进行排序。
bisect.insort_left()方法将&#34;按排序顺序在列表中插入项目&#34;:
import bisect
a = ['Alice', 'Amy', 'Andy', 'Betty', 'Eric', 'Peter', 'Richard', 'Tony']
x = 'Beatrice'
bisect.insort_left(a, x)
print(a)
['Alice', 'Amy', 'Andy', 'Beatrice', 'Betty', 'Eric', 'Peter', 'Richard', 'Tony']
答案 6 :(得分:0)
在原始python中,你可以这样做:
def ins_sorted(toIns, list): # insert a value, with respect to a sorted list
for i in range(0, len(list)):
if(toIns < list[i]):
list.insert(i, toIns) # insert the value to the left of the one it DOESNT match
break # efficiency!
return list
为什么这样做?
字符串可以像python中的数字一样进行比较! A < B
,C > B
等
公平地说:它不是最有效的选择,而bisect.insort更好,但是如果你想要自己的代码你可以控制,那就是你。
时间码:
import timeit
setupStr='''def ins_sorted(toIns, list): # insert a value, with respect to a sorted list
for i in range(0, len(list)):
if(toIns < list[i]):
list.insert(i, toIns) # insert the value to the left of the one it DOESNT match
break # efficiency!
return list'''
a = timeit.timeit('ins_sorted("c", ["a", "b", "d", "e"])', number=100000, setup=setupStr)
print(a)
b = timeit.timeit('bisect.insort(["a", "b", "d", "e"], "c")', number=100000, setup='import bisect')
print(b)
计时结果:
0.25098993408028036
0.05763813108205795
答案 7 :(得分:0)
尝试使用bisect库:
>>> import bisect
>>> someList = ["a", "b", "d"]
>>> bisect.insort(someList,'c')
>>> someList
['a', 'b', 'c', 'd']
>>>