在不使用任何内置python排序函数的情况下,对仅包含0和1的列表进行有效排序?

在不使用任何内置python排序函数的情况下,对仅包含0和1的列表进行有效排序?,python,Python,排序列表的最有效方法是什么,[0,0,1,0,1,1,0]其元素仅为0&1,而不使用任何内置的sort()或sorted()或count()函数。O(n)或小于该值,您只有两个值,因此您可以提前知道输出的精确结构:它将被划分为两个不同长度的区域。这一个是O(n)(您不能得到更少): >>> lst = [0,0,1,0,1,1,0] >>> l, s = len(lst), sum(lst) >>> result = [0] * (l - s

排序列表的最有效方法是什么,
[0,0,1,0,1,1,0]
其元素仅为
0
&
1
,而不使用任何内置的
sort()
sorted()
count()
函数。O(n)或小于该值,您只有两个值,因此您可以提前知道输出的精确结构:它将被划分为两个不同长度的区域。

这一个是
O(n)
(您不能得到更少):

>>> lst = [0,0,1,0,1,1,0]
>>> l, s = len(lst), sum(lst)
>>> result = [0] * (l - s) + [1] * s
>>> result
[0, 0, 0, 0, 1, 1, 1]
由于没有Python循环,在纯Python中,这可能会更快…

我会尝试以下方法:

b = [0,0,1,0,1,1,0]

def odd_sort(a):
  zeroes = a.count(0)

  return [0 for i in xrange(zeroes)] + [1 for i in xrange(len(a) - zeroes)]

您可以使用两个指针遍历列表,一个从开始(
i
)开始,另一个从结束(
j
),然后逐个比较值,必要时交换它们:

def sort_binary_values(l):
    i, j = 0, len(l)-1
    while i < j:
        # skip 0 values from the begin
        while i < j and l[i] == 0:
            i = i+1
        if i >= j: break
        # skip 1 values from the end
        while i < j and l[j] == 1:
            j = j-1
        if i >= j: break
        # since all in sequence values have been skipped and i and j did not reach each other
        # we encountered a pair that is out of order and needs to be swapped
        l[i], l[j] = l[j], l[i]
        j = j-1
        i = i+1
    return l
def排序二进制值(l):
i、 j=0,len(l)-1
而i=j:break
#从末尾跳过1个值
当i=j:break
#因为序列中的所有值都被跳过,并且i和j没有相互到达
#我们遇到一对出现故障,需要更换
l[i],l[j]=l[j],l[i]
j=j-1
i=i+1
返回l

def sort\u arr\u with\u zero\u one():


可以使用许多不同的通用排序算法。然而,在这种情况下,最重要的考虑是所有要排序的元素都属于集合(0,1)

正如其他贡献者回答的那样,有一个微不足道的实现

def radix_sort(a):
    slist = [[],[]]
    for elem in a:
        slist[elem].append(elem)
    return slist[0] + slist[1]

print radix_sort([0,0,1,0,1,1,0])
必须指出的是,这是一个特定的实施。如果要排序的列表中的元素属于定义的有限集合,则可以很容易地进行扩展

def radix_sort(a, elems):
    slist = {}
    for elem in elems:
        slist[elem] = []
    for elem in a:
        slist[elem].append(elem)
    nslist = []
    for elem in elems:
        nslist += slist[elem]
    return nslist

print radix_sort([2,0,0,1,3,0,1,1,0],[0,1,2,3])

没有
sort()
sorted()
count()
函数。O(n)

我喜欢JBernado的答案,但会加入另一个可怕的选项(尽管我没有对其进行任何分析-它不是特别可扩展的,因为它依赖于字典哈希的顺序,但适用于0和1):

或-稍微不太复杂…

from itertools import repeat, chain, islice, ifilter
from operator import not_

list(islice(chain(ifilter(not_, bits), repeat(1)), len(bits)))

这将使所有内容都保持在C级别,因此它应该是相当优化的。

您需要知道的是原始序列的长度以及其中有多少个序列

old = [0,0,1,0,1,1,0]
ones = sum(1 for b in old if b)
new = [0]*(len(old)-ones) + [1]*ones
这里是一个O(n)时间和O(2)空间中的Python解决方案。 绝对不需要创建新列表和最佳时间性能

def sort01(arr):
  i = 0
  j = len(arr)-1
  while i < j:
    while arr[i] == 0:
      i += 1
    while arr[j] == 1:
      j -= 1
    if i<j:
      arr[i] = 0
      arr[j] = 1
  return arr
def sort01(arr):
i=0
j=透镜(arr)-1
而i如果我
count\u of_one=sum(old)
:)
。count()对我来说快15%。使用
timeit
模块,自己看看。@Blender这就是我要说的:)测试了这个解决方案以及所有其他解决方案。它是目前最快的。@Blender,
[0,1]*10000=[0,1,0,1,0,1….]
。如果列表仅包含不可变对象(如
1
0
),则此语法安全:)是否确实要生成列表以获取其长度。它最好写为
sum(旧版if i为1)
@Jon Clements:是的,那更好。答案更新——谢谢。请不要隐藏内置函数或数据类型(
id
set
在您的情况下),值得注意的是,第一个代码块将与任何int一起工作(至少在CPython中,其中hash(int)==int),但第二个代码块纯粹是0/1I,我选择astynax的答案作为一个,因为它有更多的投票权。但我比其他人更容易理解你的话。即使你没有使用排序,排序或计数。我想也是o(n)。谢谢你的回答
from itertools import repeat, chain, islice, ifilter
from operator import not_

list(islice(chain(ifilter(not_, bits), repeat(1)), len(bits)))
old = [0,0,1,0,1,1,0]
ones = sum(1 for b in old if b)
new = [0]*(len(old)-ones) + [1]*ones
def sort01(arr):
  i = 0
  j = len(arr)-1
  while i < j:
    while arr[i] == 0:
      i += 1
    while arr[j] == 1:
      j -= 1
    if i<j:
      arr[i] = 0
      arr[j] = 1
  return arr