【问题标题】:Best way to append new number to the `range` list and sort the new list将新数字附加到“范围”列表并对新列表进行排序的最佳方法
【发布时间】:2018-07-30 20:34:35
【问题描述】:

我写 Python 已经有一段时间了。对于使这三行简洁的最佳方法是什么?

my_range = range(97, 123)     # I want a-z
my_range.append(32)           # I want space as well
my_range = sorted(my_range)   # I want it sorted (whilst not needed)

~~~~~~~~~~~~~~~~~~~~~

import random

count = 0
string = ""

my_range = range(97, 123)
my_range.append(32)
my_range = sorted(my_range)

while len(string) != 27:
    string = string + chr(random.choice(my_range))

print string

~~~~~~~~~~~~~~~~

【问题讨论】:

  • 您使用的是 Python 2 吗?因为否则这会引发错误; range 没有 append() 方法..
  • 这是一个意见导向的问题。你在这里看起来很简洁。有些人可能会建议在一行上进行堆叠操作(即my_range = sorted(range(97, 123).append(32)),但正如您所见,虽然这会使它更短,但它会增加复杂性和阅读难度。
  • 我认为不需要对您的范围进行排序。你为什么这样做?
  • 我同意,我不认为有必要,但发帖人想要的问题是,所以我把它留在那里。 :)

标签: python python-2.7 list range


【解决方案1】:

在 Python 2 中,您可以:

>>> my_range = sorted([32]+range(97,123))
>>> my_range
[32, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122]

【讨论】:

    【解决方案2】:

    单线解决方案

    在 Python 2.7 中,为了在一行中实现这一点,您可以简单地这样做:

    >>> sorted(range(97, 123) + [32])
    [32, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122]
    

    而在 Python 3.x 中,您需要将range 类型转换为list,因为它返回range 类型的对象(没有为它定义+ 运算符):

    >>> sorted(list(range(97, 123)) + [32])
    [32, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122]
    

    性能高效的解决方案(使用bisect.bisect

    但是,实现这一目标的高效方法将使用bisect.bisect,它会给出相同的结果,而无需对列表执行排序。此解决方案基于 range 列表已排序的事实。因此,在保持sortedness 的排序列表中的正确位置插入新数字(无需显式排序列表)。以下是说明行为的示例:

    from bisect import bisect
    
    # Example 1: when new number falls inside the range
    my_range = list(range(31, 35))
    my_range.insert(bisect(my_range, 32), 32)
    # where `my_range` will hold `[31, 32, 32, 33, 34]`
    
    # Example 2: when new number falls before the range
    my_range = list(range(97, 102))
    my_range.insert(bisect(my_range, 32), 32)
    # where `my_range` will hold `[32, 97, 98, 99, 100, 101]`
    
    # Example 3: when new number falls after the range
    my_range = list(range(25, 30))
    my_range.insert(bisect(my_range, 32), 32)
    # where `my_range` will hold `[25, 26, 27, 28, 29, 32]`
    

    性能比较

    下面是上述两种解决方案在 Python 3 中timeit 的比较。随着range 的大小会增加,两种解决方案之间的时间差会成比例地增加。

    • 使用 sorted(...) (每个循环 1.91 微秒)

      mquadri$ python3 -m timeit "sorted(list(range(97, 123)) + [32])"
      100000 loops, best of 3: 1.91 usec per loop
      
    • 使用 bisect.bisect(...) (每个循环 1.18 微秒)

      mquadri$ python3 -m timeit -s "from bisect import bisect" "my_range = list(range(97, 123));  my_range.insert(bisect(my_range, 32), 32)"
      1000000 loops, best of 3: 1.18 usec per loop
      

    【讨论】:

      猜你喜欢
      • 2019-01-01
      • 2017-07-15
      • 2012-05-05
      • 1970-01-01
      • 1970-01-01
      • 2012-09-17
      • 2015-08-12
      • 2020-06-12
      • 1970-01-01
      相关资源
      最近更新 更多