如何在python中的单词中插入一个单词?

时间:2018-06-12 23:39:30

标签: python list sorting

我有一个清单。

我需要在列表中添加一个单词,但我不知道该怎么做。

例如,

我有一个list = ['Alice', 'Amy', 'Andy', 'Betty', 'Eric', 'Peter', 'Richard', 'Tony']

8 个答案:

答案 0 :(得分:4)

您可以使用sortedcontainers等专家库,每次插入后效率高于幼稚list.sortSortedList.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>

如果您想要充分利用这两个方面,您需要一个更复杂的数据结构:

  • 某种平衡的二叉搜索树(红黑色,AVL等)是传统的答案,虽然它在实践中往往很慢。
  • 与任何B树变体一样,更广泛的搜索树可以避免二叉树的大部分性能成本(并允许您使用更高的日志基础进行搜索,以启动)。
  • 跳过列表是一个链接列表,其中有日志N“更高级别”链接列表穿过它(或堆叠在它上面),因此您可以将其平分。此“索引列表”概念还有其他变体。
  • 复杂的混合动力车有多种Python实现,例如deque / rope结构,顶部有可选的B树变体。

常用的实施包括blist.sortedlistsortedcontainers.SortedListpybst.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']

使用链接列表,您可以在单个方法中执行addinsert操作,并应用其他逻辑:

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 < BC > 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']
>>>