在Python中对字节和元组进行排序
我到处找了找,似乎找不到正确的方法来对一个包含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 个回答
如果你把 grouper
和 flatten
这两个函数(可以参考 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))
,不过我想只有那些特别喜欢函数式编程的人才会喜欢这样做。
元组是不可变的,也就是说一旦创建了就不能修改它们。如果你想修改里面的某个元素,最好把数据放在一个可以改变的集合里,比如列表。你可以使用内置的函数 list
和 tuple
来在元组和列表之间转换。
另外,你也可以使用 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
的前提是你的元组元素数量是偶数(根据你的问题,这种情况是成立的)。
元组是不能被改变的,它们是不可变的。不过,你可以用一个新的元组来替换它,按照你想要的方式排列(我不会称你想要的方式为“排序”)。要做到这一点,只需要交换原始元组中每一对元素的位置。
这里有一个简单的实现方法。请注意,如果元素的数量是奇数,最后一个元素会保持不变,因为你没有说明想要如何处理这种情况。处理这种可能性会稍微让代码复杂一些。
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)