Mevcut cevaplar yalnızca Unicode Değiştiricileri / grafik kümeleri yoksayılırsa doğrudur. Bununla daha sonra ilgileneceğim, ancak önce bazı ters algoritmaların hızına bir göz atın:
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
Liste anlama zamanının ( reversed = string[::-1]
) her durumda (yazım hatalarını düzelttikten sonra bile) çok düşük olduğunu görebilirsiniz.
Dize Ters Çevirme
Eğer gerçekten bir anlamda bir dizgeyi tersine çevirmek istiyorsanız, WAY daha karmaşıktır. Örneğin, aşağıdaki dizeyi alın ( kahverengi parmak sola , sarı parmak yukarı dönük ). Bunlar iki grafiktir, ancak 3 adet unicode kod noktasıdır. Ek olarak bir cilt değiştirici .
example = "👈🏾👆"
Ancak verilen yöntemlerden herhangi biriyle ters çevirirseniz, kahverengi parmak yukarı , sarı parmak sola bakacaksınız . Bunun nedeni, "kahverengi" renk değiştiricinin hala ortada olması ve önündeki her şeye uygulanmasıdır. Böylece sahibiz
- U: parmak yukarı dönük
- M: kahverengi değiştirici
- L: parmak sola dönük
ve
original: LMU
reversed: UML (above solutions)
reversed: ULM (correct reversal)
Unicode Grapheme Kümeleri , yalnızca değiştirici kod noktalarından biraz daha karmaşıktır. Neyse ki, grafik haritalarını işlemek için bir kütüphane var :
>>> import grapheme
>>> g = grapheme.graphemes("👈🏾👆")
>>> list(g)
['👈🏾', '👆']
ve dolayısıyla doğru cevap
def reverse_graphemes(string):
g = list(grapheme.graphemes(string))
return ''.join(g[::-1])
bu da açık ara en yavaş olanı:
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
Kod
#!/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()