मौजूदा उत्तर केवल तभी सही होते हैं जब यूनिकोड संशोधक / ग्रेपैम क्लस्टर को अनदेखा किया जाता है। मैं बाद में उससे निपटूंगा, लेकिन पहले कुछ उलट एल्गोरिदम की गति पर एक नज़र डालनी चाहिए:
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
आप देख सकते हैं कि लिस्ट कॉम्प्रिहेंशन ( reversed = string[::-1]
) का समय सभी मामलों में सबसे कम (मेरी टाइपो को ठीक करने के बाद भी) है।
स्ट्रिंग उलट
यदि आप वास्तव में सामान्य अर्थों में एक स्ट्रिंग को उल्टा करना चाहते हैं, तो यह अधिक जटिल है। उदाहरण के लिए, निम्न स्ट्रिंग लें ( बाईं ओर इशारा करते हुए भूरे रंग की उंगली , पीली उंगली की ओर इशारा करते हुए )। वे दो अंगूर हैं, लेकिन 3 यूनिकोड कोड पॉइंट हैं। अतिरिक्त एक त्वचा संशोधक है ।
example = "👈🏾👆"
लेकिन अगर आप इसे दिए गए तरीकों में से किसी के साथ उलटते हैं, तो आपको भूरे रंग की उंगली की ओर इशारा मिलता है , पीले रंग की उंगली बाईं ओर इशारा करती है । इसका कारण यह है कि "ब्राउन" रंग संशोधक अभी भी बीच में है और इसके पहले जो कुछ भी है, उस पर लागू होता है। तो हमारे पास
- U: उंगली की ओर इशारा करते हुए
- एम: ब्राउन संशोधक
- एल: उंगली बाईं ओर इशारा करते हुए
तथा
original: LMU
reversed: UML (above solutions)
reversed: ULM (correct reversal)
यूनिकोड ग्रेफेम क्लस्टर्स सिर्फ संशोधक कोड बिंदुओं की तुलना में थोड़ा अधिक जटिल हैं। सौभाग्य से, अंगूरों को संभालने के लिए एक पुस्तकालय है :
>>> import grapheme
>>> g = grapheme.graphemes("👈🏾👆")
>>> list(g)
['👈🏾', '👆']
और इसलिए सही उत्तर होगा
def reverse_graphemes(string):
g = list(grapheme.graphemes(string))
return ''.join(g[::-1])
जो अब तक सबसे धीमा है:
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
कोड
#!/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()