使用Python,切换列表中每个其他元素的位置的最有效方法是什么?
例如,我试图在A切换后获得每个字母的字母顺序列表,如下所示:
import string
alphabet = string.ascii_uppercase
# ABCDEFGHIJKLMNOPQRSTUVWXYZ
switched_alphabet = do_something_magic(alphabet)
# ACBEDGF...
# position 1, 3, 2, 5, 4, 7, 6...
答案 0 :(得分:6)
>>> import string
>>> alphabet = list(string.ascii_uppercase)
>>> for i in range(2, len(alphabet), 2):
... alphabet[i], alphabet[i-1] = alphabet[i-1], alphabet[i]
...
>>> alphabet
['A', 'C', 'B', 'E', 'D', 'G', 'F', 'I', 'H', 'K', 'J', 'M', 'L', 'O', 'N', 'Q', 'P', 'S', 'R', 'U', 'T', 'W', 'V', 'Y', 'X', 'Z']
>>>
答案 1 :(得分:2)
另一种方法(使用切片并且比for
循环快得多):
def switch(string, n=1):
data = list(string)
odd = -1 if (len(data)-n) % 2 else len(data)
data[n:odd:2], data[n+1::2] = data[n+1::2], data[n:odd:2]
return ''.join(data)
>>> switch(string.ascii_uppercase)
'ACBEDGFIHKJMLONQPSRUTWVYXZ'
n
是您要保留的商品数量。有一个处理奇数长度字符串的技巧。
答案 2 :(得分:1)
以下是如何完成的
使用的工具
alphabet = string.ascii_uppercase
#The Even Series using itertools.compress
[x for x in itertools.compress(alphabet[1:],[0,1]*(len(alphabet)/2))]
['C', 'E', 'G', 'I', 'K', 'M', 'O', 'Q', 'S', 'U', 'W', 'Y']
#The Odd Series
[x for x in itertools.compress(alphabet[1:],[1,0]*(len(alphabet)/2))]
['B', 'D', 'F', 'H', 'J', 'L', 'N', 'P', 'R', 'T', 'V', 'X', 'Z']
#Now Join it with itertools.izip
[''.join(x) for x in itertools.izip((x for x in itertools.compress(alphabet[1:],[0,1]*(len(alphabet)/2))),
(x for x in itertools.compress(alphabet[1:],[1,0]*(len(alphabet)/2))))]
['CB', 'ED', 'GF', 'IH', 'KJ', 'ML', 'ON', 'QP', 'SR', 'UT', 'WV', 'YX']
#Finally Join as a Single String prefixing and
#suffixing the first and the last character
alphabet[0]+''.join(''.join(x) for x in itertools.izip((x for x in itertools.compress(alphabet[1:],[0,1]*(len(alphabet)/2))),
(x for x in itertools.compress(alphabet[1:],[1,0]*(len(alphabet)/2)))))
+alphabet[-1]
'ACBEDGFIHKJMLONQPSRUTWVYXZ'
所以最终的解决方案是
alphabet[0]+
''.join(''.join(x) for x in itertools.izip(
itertools.compress(alphabet[1:],[0,1]*(len(alphabet)/2)),
itertools.compress(alphabet[1:],[1,0]*(len(alphabet)/2))))
+alphabet[-1]
注* * 的
正如@ J.F.Sebastian指出的那样,我们可以使用imap,这会简化上面的表达式
alphabet[0]+
"".join(itertools.imap("".join, itertools.izip(
itertools.compress(alphabet[1:], itertools.cycle([0,1])),
itertools.compress(alphabet[1:], itertools.cycle([1,0]))))
+alphabet[-1]
答案 3 :(得分:1)
内部索引:
''.join(alphabet[i + (-1)**(i%2==0)] for i in xrange(1, len(alphabet)-1))
# -> CBEDGFIHKJMLONQPSRUTWVYX
相同 - 使用itertools:
from itertools import cycle, izip
''.join(alphabet[i+j] for i,j in izip(xrange(1,len(alphabet)-1), cycle([1,-1])))
第一个和最后一个职位留作练习。