Các câu trả lời hiện tại chỉ đúng nếu cụm điều chỉnh / biểu đồ Unicode bị bỏ qua. Tôi sẽ giải quyết vấn đề đó sau, nhưng trước tiên hãy xem tốc độ của một số thuật toán đảo ngược:
list_comprehension : min: 0.6μs, mean: 0.6μs, max: 2.2μs
reverse_func : min: 1.9μs, mean: 2.0μs, max: 7.9μs
reverse_reduce : min: 5.7μs, mean: 5.9μs, max: 10.2μs
reverse_loop : min: 3.0μs, mean: 3.1μs, max: 6.8μs
list_comprehension : min: 4.2μs, mean: 4.5μs, max: 31.7μs
reverse_func : min: 75.4μs, mean: 76.6μs, max: 109.5μs
reverse_reduce : min: 749.2μs, mean: 882.4μs, max: 2310.4μs
reverse_loop : min: 469.7μs, mean: 577.2μs, max: 1227.6μs
Bạn có thể thấy rằng thời gian để hiểu danh sách ( reversed = string[::-1]
) trong mọi trường hợp là thấp nhất (ngay cả sau khi sửa lỗi đánh máy của tôi).
Chuỗi đảo ngược
Nếu bạn thực sự muốn đảo ngược một chuỗi theo nghĩa thông thường, thì đó là CÁCH phức tạp hơn. Ví dụ: lấy chuỗi sau ( ngón tay nâu chỉ trái , ngón tay vàng hướng lên ). Đó là hai biểu đồ, nhưng 3 điểm mã unicode. Một bổ sung là một sửa đổi da .
example = "👈🏾👆"
Nhưng nếu bạn đảo ngược nó với bất kỳ phương pháp nào, bạn sẽ thấy ngón tay nâu chỉ lên , ngón tay vàng chỉ sang trái . Lý do cho điều này là công cụ sửa đổi màu "nâu" vẫn ở giữa và được áp dụng cho bất cứ điều gì trước nó. Vì vậy chúng tôi có
- U: ngón tay chỉ lên
- M: sửa đổi màu nâu
- L: ngón tay trỏ trái
và
original: LMU
reversed: UML (above solutions)
reversed: ULM (correct reversal)
Các cụm đồ thị Unicode phức tạp hơn một chút so với chỉ các điểm mã sửa đổi. May mắn thay, có một thư viện để xử lý đồ thị :
>>> import grapheme
>>> g = grapheme.graphemes("👈🏾👆")
>>> list(g)
['👈🏾', '👆']
và do đó câu trả lời đúng sẽ là
def reverse_graphemes(string):
g = list(grapheme.graphemes(string))
return ''.join(g[::-1])
đó cũng là chậm nhất:
list_comprehension : min: 0.5μs, mean: 0.5μs, max: 2.1μs
reverse_func : min: 68.9μs, mean: 70.3μs, max: 111.4μs
reverse_reduce : min: 742.7μs, mean: 810.1μs, max: 1821.9μs
reverse_loop : min: 513.7μs, mean: 552.6μs, max: 1125.8μs
reverse_graphemes : min: 3882.4μs, mean: 4130.9μs, max: 6416.2μs
Mật mã
#!/usr/bin/env python
import numpy as np
import random
import timeit
from functools import reduce
random.seed(0)
def main():
longstring = ''.join(random.choices("ABCDEFGHIJKLM", k=2000))
functions = [(list_comprehension, 'list_comprehension', longstring),
(reverse_func, 'reverse_func', longstring),
(reverse_reduce, 'reverse_reduce', longstring),
(reverse_loop, 'reverse_loop', longstring)
]
duration_list = {}
for func, name, params in functions:
durations = timeit.repeat(lambda: func(params), repeat=100, number=3)
duration_list[name] = list(np.array(durations) * 1000)
print('{func:<20}: '
'min: {min:5.1f}μs, mean: {mean:5.1f}μs, max: {max:6.1f}μs'
.format(func=name,
min=min(durations) * 10**6,
mean=np.mean(durations) * 10**6,
max=max(durations) * 10**6,
))
create_boxplot('Reversing a string of length {}'.format(len(longstring)),
duration_list)
def list_comprehension(string):
return string[::-1]
def reverse_func(string):
return ''.join(reversed(string))
def reverse_reduce(string):
return reduce(lambda x, y: y + x, string)
def reverse_loop(string):
reversed_str = ""
for i in string:
reversed_str = i + reversed_str
return reversed_str
def create_boxplot(title, duration_list, showfliers=False):
import seaborn as sns
import matplotlib.pyplot as plt
import operator
plt.figure(num=None, figsize=(8, 4), dpi=300,
facecolor='w', edgecolor='k')
sns.set(style="whitegrid")
sorted_keys, sorted_vals = zip(*sorted(duration_list.items(),
key=operator.itemgetter(1)))
flierprops = dict(markerfacecolor='0.75', markersize=1,
linestyle='none')
ax = sns.boxplot(data=sorted_vals, width=.3, orient='h',
flierprops=flierprops,
showfliers=showfliers)
ax.set(xlabel="Time in ms", ylabel="")
plt.yticks(plt.yticks()[0], sorted_keys)
ax.set_title(title)
plt.tight_layout()
plt.savefig("output-string.png")
if __name__ == '__main__':
main()