在Python中对字节和元组进行排序

1 投票
3 回答
1083 浏览
提问于 2025-04-16 09:59

我到处找了找,似乎找不到正确的方法来对一个包含32个元素的元组进行排序,具体是要把每个奇数和偶数位置的元素互换。

比如:

1 0 3 2 5 4 7 6 9 8
to
0 1 2 3 4 5 6 7 8 9

我现在的代码是这样的:

i=0
nd = []
while i < len(self.r.ipDeviceName):
  print(i)
    if i%2:
      nd[i]=self.r.ipDeviceName[i-1]
    else:
      nd[i]=self.r.ipDeviceName[i+1]
dn = "".join(map(chr,nd))
devicenameText.SetValue(dn)

这里的self.r.ipDeviceName是一个元组,但我要么遇到索引错误,要么遇到元组不支持赋值,这取决于我代码的不同变化。

我也试过这样做,结果还是一样:

nd = self.r.ipDeviceName
for i in nd:
    if i&0x01:
        nd[i]=self.r.ipDeviceName[i-1]
    else:
        nd[i]=self.r.ipDeviceName[i+1]
dn = "".join(map(chr,nd))
devicenameText.SetValue(dn)

结果还是一样。看起来很简单的事情我就是搞不明白。谢谢你的帮助和时间。

3 个回答

0

如果你把 grouperflatten 这两个函数(可以参考 itertools 的一些用法)加入到你的工具箱里,你就可以这样做:

xs = [1, 0, 3, 2, 5, 4, 7, 6, 9, 8]
xs2 = flatten((y, x) for (x, y) in grouper(2, xs))
# list(xs2) => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

你甚至可以写 flatten(imap(reversed, grouper(2, xs)),不过我想只有那些特别喜欢函数式编程的人才会喜欢这样做。

3

元组是不可变的,也就是说一旦创建了就不能修改它们。如果你想修改里面的某个元素,最好把数据放在一个可以改变的集合里,比如列表。你可以使用内置的函数 listtuple 来在元组和列表之间转换。

另外,你也可以使用 zip 这种函数式的方法,从现有的元组创建一个新的元组,而不改变原来的元组:

>>> t = tuple(range(10))
>>> tuple(x for i in zip(t[1::2], t[::2]) for x in i)
(1, 0, 3, 2, 5, 4, 7, 6, 9, 8)

或者你可以使用 itertools.chain

>>> import itertools
>>> tuple(itertools.chain(*zip(t[1::2], t[::2])))
(1, 0, 3, 2, 5, 4, 7, 6, 9, 8)

需要注意的是,这里使用 zip 的前提是你的元组元素数量是偶数(根据你的问题,这种情况是成立的)。

0

元组是不能被改变的,它们是不可变的。不过,你可以用一个新的元组来替换它,按照你想要的方式排列(我不会称你想要的方式为“排序”)。要做到这一点,只需要交换原始元组中每一对元素的位置。

这里有一个简单的实现方法。请注意,如果元素的数量是奇数,最后一个元素会保持不变,因为你没有说明想要如何处理这种情况。处理这种可能性会稍微让代码复杂一些。

def swap_even_odd_entries(seq):
    tmp = list(seq)+[seq[-1]]  # convert sequence to mutable list and dup last
    for i in xrange(0, len(seq), 2):
        tmp[i],tmp[i+1] = tmp[i+1],tmp[i]  # swap each entry with following one
    return tuple(tmp[:len(seq)])  # remove any excess

a = (1, 0, 3, 2, 5, 4, 7, 6, 9, 8)
a = swap_even_odd_entries(a)
b = (91, 70, 23, 42, 75, 14, 87, 36, 19, 80)
b = swap_even_odd_entries(b)
c = (1, 0, 3, 2, 5)
c = swap_even_odd_entries(c)
print a
print b
print c
# output
#  (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
#  (70, 91, 42, 23, 14, 75, 36, 87, 80, 19)
#  (0, 1, 2, 3, 5)

同样的事情也可以用一种不太容易读懂的方式来实现,写成一个长长的表达式。同样地,如果长度是奇数,最后一个元素也不会改变。

swap_even_odd_entries2 = lambda t: tuple(
    v for p in [(b,a) for a,b in zip(*[iter(t)]*2) + [(t[-1],)*2]]
        for v in p)[:len(t)]

a = (1, 0, 3, 2, 5, 4, 7, 6, 9, 8)
a = swap_even_odd_entries2(a)
b = (91, 70, 23, 42, 75, 14, 87, 36, 19, 80)
b = swap_even_odd_entries2(b)
c = (1, 0, 3, 2, 5)
c = swap_even_odd_entries2(c)
print
print a
print b
print c
# output
#  (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
#  (70, 91, 42, 23, 14, 75, 36, 87, 80, 19)
#  (0, 1, 2, 3, 5)

撰写回答