鉴于以下情况:
import string
UPPERCASE_ALPHABET = list(string.ascii_uppercase)
LOWERCASE_ALPHABET = list(string.ascii_lowercase)
如何在跳过N个位置的字母表上创建一个循环循环?
示例1 :
信 = a,跳 = 5
结果:f
示例2 :
信件 = z,跳 = 5
结果:e
到目前为止,我得到了:
import string
UPPERCASE_ALPHABET = list(string.ascii_uppercase)
LOWERCASE_ALPHABET = list(string.ascii_lowercase)
def forward(letter, jump):
alphabet = LOWERCASE_ALPHABET if letter.islower() else UPPERCASE_ALPHABET
index = alphabet.index(letter)
count = 0
while True:
if count == jump:
return alphabet[index]
if index == len(alphabet):
index = 0
index += 1
count += 1
print forward('a', 5)
print forward('z', 5)
但它看起来根本不是Pythonic ......
有更好的Pythonic方法吗?也许使用chr(ord('N')+位置)?
答案 0 :(得分:1)
我编写了一个自定义迭代器类来封装itertools.cycle()
并提供skip()
功能,例如:
import itertools
class CyclicSkipIterator(object):
def __init__(self, iterable):
self._iterator = itertools.cycle(iterable)
def __iter__(self):
return self
def next(self): # use __next__ on Python 3.x
return next(self._iterator)
def skip(self, number=1):
for i in xrange(number): # use range() on Python 3.x
next(self._iterator)
然后你可以用它完成你想要的东西:
import string
LOWERCASE_ALPHABET = list(string.ascii_lowercase)
lower_iter = CyclicSkipIterator(LOWERCASE_ALPHABET)
print(next(lower_iter)) # a
lower_iter.skip(4) # skip next 4 letters: b, c, d, e
print(next(lower_iter)) # f
lower_iter.skip(19) # skip another 19 letters to arrive at z
print(next(lower_iter)) # z
lower_iter.skip(4) # skip next 4 letters: a, b, c, d
print(next(lower_iter)) # e
如果您愿意,可以添加更多功能,例如反转,迭代中迭代等等。
更新:如果您想跳转到列表中的特定元素,可以为CyclicSkipIterator
添加一个方法:
class CyclicSkipIterator(object):
def __init__(self, iterable):
self._iterator = itertools.cycle(iterable)
def __iter__(self):
return self
def __next__(self): # use __next__ on Python 3.x
return next(self._iterator)
def skip(self, number=1):
for _ in range(number): # use range() on Python 3.x
next(self._iterator)
def skip_to(self, element, max_count=100): # max_count protects against endless cycling
max_count = max(1, max_count) # ensure at least one iteration
for _ in range(max_count): # use range() on Python 3.x
e = next(self._iterator)
if element == e:
break
然后你可以跳过任何你想要的字母:
import string
LOWERCASE_ALPHABET = list(string.ascii_lowercase)
lower_iter = CyclicSkipIterator(LOWERCASE_ALPHABET)
print(next(lower_iter)) # a
lower_iter.skip(4) # skip 4 letters: b, c, d, e
print(next(lower_iter)) # f
lower_iter.skip_to("y") # skip all letters up to y
print(next(lower_iter)) # z
lower_iter.skip(4) # skip 4 letters: a, b, c, d
print(next(lower_iter)) # e
答案 1 :(得分:1)
我认为您对ord
和chr
:
import string
def forward(letter, jump):
if letter.islower():
start_character = ord('a')
else:
start_character = ord('A')
start = ord(letter) - start_character
offset = ((start + jump) % 26) + start_character
result = chr(offset)
return result
print forward('a', 5)
print forward('z', 5)
print forward('z', 1)
print forward('a', 26)
print forward('A', 5)
print forward('Z', 5)
print forward('Z', 1)
print forward('A', 26)
<强>输出强>
f
e
a
a
F
E
A
A
答案 2 :(得分:0)
class CyclicIterator:
def __init__(self,lst):
self.lst=lst
self.i=0
def __iter__(self):
return self
def __next__(self):
result=self.lst[self.i % len(self.lst)]
self.i+=3 #increasing by 3
return result
具有 iter ()和 next ()的类符合迭代器协议。创建此迭代器类的实例
iter_cycle=CyclicIterator('abcdefghiijklmnnoprstuvyz')
numbers=range(1,27,3) # 26 letters increases by 3
list(zip(list(numbers),iter_cycle))