স্ট্রিংয়ে একাধিক অক্ষর প্রতিস্থাপনের সেরা উপায়?


198

আমাকে কয়েকটি চরিত্রগুলি নিম্নরূপে প্রতিস্থাপন করতে হবে: &\&, #\#, ...

আমি নীচে কোড করেছিলাম, তবে আমার ধারণা আরও কিছু ভাল উপায় হওয়া উচিত। কোন ইঙ্গিত?

strs = strs.replace('&', '\&')
strs = strs.replace('#', '\#')
...

উত্তর:


432

দুটি অক্ষর প্রতিস্থাপন করা হচ্ছে

আমি একটি অতিরিক্ত অতিরিক্ত বরাবর বর্তমান জবাবগুলিতে সমস্ত পদ্ধতি নির্ধারণ করেছি।

এর একটি ইনপুট স্ট্রিং সঙ্গে abc&def#ghiএবং প্রতিস্থাপন & -> \ & এবং # -> \ #, দ্রুততম উপায় একসাথে এই মত প্রতিস্থাপন চেইন ছিল: text.replace('&', '\&').replace('#', '\#')

প্রতিটি ফাংশনের সময়:

  • ক) 1000000 লুপ, প্রতি লুপে 3: 1.47 of এস সেরা
  • খ) 1000000 লুপ, প্রতি লুপে 3: 1.51 μ এস সেরা
  • গ) 100000 লুপ, প্রতি লুপে 3: 12.3 μ সর্বোত্তম
  • d) 100000 লুপ, প্রতি লুপে 3: 12। সেরা
  • e) 100000 লুপ, প্রতি লুপে 3: 3.27 μ সর্বোত্তম
  • চ) 1000000 লুপ, প্রতি লুপে 3: 0.817 μ এস সেরা
  • ছ) 100000 লুপ, প্রতি লুপে 3: 3.64 μ এর সেরা
  • জ) 1000000 লুপগুলি, প্রতি লুপে 3: 0.927 μ সর্বোত্তম
  • i) 1000000 লুপ, প্রতি লুপে 3: 0.814 μ এস সেরা

ফাংশনগুলি এখানে:

def a(text):
    chars = "&#"
    for c in chars:
        text = text.replace(c, "\\" + c)


def b(text):
    for ch in ['&','#']:
        if ch in text:
            text = text.replace(ch,"\\"+ch)


import re
def c(text):
    rx = re.compile('([&#])')
    text = rx.sub(r'\\\1', text)


RX = re.compile('([&#])')
def d(text):
    text = RX.sub(r'\\\1', text)


def mk_esc(esc_chars):
    return lambda s: ''.join(['\\' + c if c in esc_chars else c for c in s])
esc = mk_esc('&#')
def e(text):
    esc(text)


def f(text):
    text = text.replace('&', '\&').replace('#', '\#')


def g(text):
    replacements = {"&": "\&", "#": "\#"}
    text = "".join([replacements.get(c, c) for c in text])


def h(text):
    text = text.replace('&', r'\&')
    text = text.replace('#', r'\#')


def i(text):
    text = text.replace('&', r'\&').replace('#', r'\#')

সময় মতো:

python -mtimeit -s"import time_functions" "time_functions.a('abc&def#ghi')"
python -mtimeit -s"import time_functions" "time_functions.b('abc&def#ghi')"
python -mtimeit -s"import time_functions" "time_functions.c('abc&def#ghi')"
python -mtimeit -s"import time_functions" "time_functions.d('abc&def#ghi')"
python -mtimeit -s"import time_functions" "time_functions.e('abc&def#ghi')"
python -mtimeit -s"import time_functions" "time_functions.f('abc&def#ghi')"
python -mtimeit -s"import time_functions" "time_functions.g('abc&def#ghi')"
python -mtimeit -s"import time_functions" "time_functions.h('abc&def#ghi')"
python -mtimeit -s"import time_functions" "time_functions.i('abc&def#ghi')"

17 টি অক্ষর প্রতিস্থাপন করা হচ্ছে

এখানে একই কাজ করতে হবে তবে পালাতে আরও অক্ষর রয়েছে (\ `* _ {}> # + -।! $):

def a(text):
    chars = "\\`*_{}[]()>#+-.!$"
    for c in chars:
        text = text.replace(c, "\\" + c)


def b(text):
    for ch in ['\\','`','*','_','{','}','[',']','(',')','>','#','+','-','.','!','$','\'']:
        if ch in text:
            text = text.replace(ch,"\\"+ch)


import re
def c(text):
    rx = re.compile('([&#])')
    text = rx.sub(r'\\\1', text)


RX = re.compile('([\\`*_{}[]()>#+-.!$])')
def d(text):
    text = RX.sub(r'\\\1', text)


def mk_esc(esc_chars):
    return lambda s: ''.join(['\\' + c if c in esc_chars else c for c in s])
esc = mk_esc('\\`*_{}[]()>#+-.!$')
def e(text):
    esc(text)


def f(text):
    text = text.replace('\\', '\\\\').replace('`', '\`').replace('*', '\*').replace('_', '\_').replace('{', '\{').replace('}', '\}').replace('[', '\[').replace(']', '\]').replace('(', '\(').replace(')', '\)').replace('>', '\>').replace('#', '\#').replace('+', '\+').replace('-', '\-').replace('.', '\.').replace('!', '\!').replace('$', '\$')


def g(text):
    replacements = {
        "\\": "\\\\",
        "`": "\`",
        "*": "\*",
        "_": "\_",
        "{": "\{",
        "}": "\}",
        "[": "\[",
        "]": "\]",
        "(": "\(",
        ")": "\)",
        ">": "\>",
        "#": "\#",
        "+": "\+",
        "-": "\-",
        ".": "\.",
        "!": "\!",
        "$": "\$",
    }
    text = "".join([replacements.get(c, c) for c in text])


def h(text):
    text = text.replace('\\', r'\\')
    text = text.replace('`', r'\`')
    text = text.replace('*', r'\*')
    text = text.replace('_', r'\_')
    text = text.replace('{', r'\{')
    text = text.replace('}', r'\}')
    text = text.replace('[', r'\[')
    text = text.replace(']', r'\]')
    text = text.replace('(', r'\(')
    text = text.replace(')', r'\)')
    text = text.replace('>', r'\>')
    text = text.replace('#', r'\#')
    text = text.replace('+', r'\+')
    text = text.replace('-', r'\-')
    text = text.replace('.', r'\.')
    text = text.replace('!', r'\!')
    text = text.replace('$', r'\$')


def i(text):
    text = text.replace('\\', r'\\').replace('`', r'\`').replace('*', r'\*').replace('_', r'\_').replace('{', r'\{').replace('}', r'\}').replace('[', r'\[').replace(']', r'\]').replace('(', r'\(').replace(')', r'\)').replace('>', r'\>').replace('#', r'\#').replace('+', r'\+').replace('-', r'\-').replace('.', r'\.').replace('!', r'\!').replace('$', r'\$')

একই ইনপুট স্ট্রিংয়ের ফলাফল এখানে abc&def#ghi:

  • ক) 100000 লুপ, প্রতি লুপে 3: 6.72 μ সেরা
  • খ) 100000 লুপ, প্রতি লুপ 3: 2.64 μ এর সেরা
  • গ) 100000 লুপ, প্রতি লুপ 3: 11.9 of এর সেরা of
  • d) 100000 লুপ, প্রতি লুপে 3: 4.92 μ সর্বোত্তম
  • e) 100000 লুপ, প্রতি লুপে 3: 2.96 μ সর্বোত্তম
  • চ) 100000 লুপ, প্রতি লুপে 3: 4.29 of সর্বোত্তম
  • ছ) 100000 লুপ, প্রতি লুপে 3: 4.68 μ সর্বোত্তম
  • জ) 100000 লুপ, প্রতি লুপে 3: 4.73 μ সর্বোত্তম
  • i) 100000 লুপ, প্রতি লুপে 3: 4.24 μ সেরা

এবং একটি দীর্ঘ ইনপুট স্ট্রিং সহ ( ## *Something* and [another] thing in a longer sentence with {more} things to replace$):

  • ক) 100000 লুপ, প্রতি লুপ 3: 7.59 μ এর সেরা
  • খ) 100000 লুপ, প্রতি লুপ 3: 6.54 μ এর সেরা
  • গ) 100000 লুপ, প্রতি লুপ 3: 16.9 μ এর সেরা
  • d) 100000 লুপ, প্রতি লুপে 3: 7.29 μ সর্বোত্তম
  • e) 100000 লুপ, প্রতি লুপে 3: 12.2। সেরা
  • চ) 100000 লুপ, প্রতি লুপ 3: 5.38 μ এস সেরা of
  • ছ) 10000 লুপ, প্রতি লুপে 3: 21.7 μ সর্বোত্তম
  • জ) 100000 লুপ, প্রতি লুপে 3: 5.7 μ সর্বোত্তম
  • i) 100000 লুপ, প্রতি লুপে 3: 5.13 μ এস সেরা

বেশ কয়েকটি রূপ যুক্ত করা হচ্ছে:

def ab(text):
    for ch in ['\\','`','*','_','{','}','[',']','(',')','>','#','+','-','.','!','$','\'']:
        text = text.replace(ch,"\\"+ch)


def ba(text):
    chars = "\\`*_{}[]()>#+-.!$"
    for c in chars:
        if c in text:
            text = text.replace(c, "\\" + c)

সংক্ষিপ্ত ইনপুট সহ:

  • ab) 100000 লুপ, প্রতি লুপে 3: 7.05 μ এস সেরা
  • বা) 100000 লুপ, প্রতি লুপে 3: 2.4 of সেরা

দীর্ঘ ইনপুট সহ:

  • ab) 100000 লুপ, প্রতি লুপে 3: 7.71। সর্বোত্তম
  • বা) 100000 লুপ, প্রতি লুপে 3: 6.08 of এস সেরা

সুতরাং আমি baপাঠযোগ্যতা এবং গতির জন্য ব্যবহার করতে যাচ্ছি ।

অভিযোজ্য বস্তু

মন্তব্য haccks দ্বারা প্রণোদিত করা হয়, মধ্যে এক পার্থক্য abএবং baহয় if c in text:চেক। আসুন তাদের আরও দুটি বৈকল্পের বিপরীতে পরীক্ষা করুন:

def ab_with_check(text):
    for ch in ['\\','`','*','_','{','}','[',']','(',')','>','#','+','-','.','!','$','\'']:
        if ch in text:
            text = text.replace(ch,"\\"+ch)

def ba_without_check(text):
    chars = "\\`*_{}[]()>#+-.!$"
    for c in chars:
        text = text.replace(c, "\\" + c)

পাইথন ২.7.১৪ এবং ৩.6.৩ এ লুপ প্রতি টাইমস এবং পূর্ববর্তী সেট থেকে আলাদা মেশিনে, তাই সরাসরি তুলনা করা যায় না।

╭────────────╥──────┬───────────────┬──────┬──────────────────╮
 Py, input    ab   ab_with_check   ba   ba_without_check 
╞════════════╬══════╪═══════════════╪══════╪══════════════════╡
 Py2, short  8.81     4.22        3.45     8.01          
 Py3, short  5.54     1.34        1.46     5.34          
├────────────╫──────┼───────────────┼──────┼──────────────────┤
 Py2, long   9.3      7.15        6.85     8.55          
 Py3, long   7.43     4.38        4.41     7.02          
└────────────╨──────┴───────────────┴──────┴──────────────────┘

আমরা এই সিদ্ধান্তে পৌঁছাতে পারি:

  • চেকটি থাকা ব্যক্তিরা চেকটি নেই তাদের চেয়ে 4x পর্যন্ত দ্রুত

  • ab_with_checkপাইথন 3 তে সামান্য লিডে রয়েছে তবে পাইথন 2 তে ba(চেক সহ) এর বেশি লিড রয়েছে

  • তবে, এখানে সবচেয়ে বড় পাঠ পাইথন 3 পাইথন 2 এর তুলনায় 3x দ্রুততর ! পাইথন 3 এর ধীরতম এবং পাইথন 2-তে দ্রুততম মধ্যে কোনও বিশাল পার্থক্য নেই!


4
কেন এই ব্যতিক্রম উত্তর নয়?
চিকেন স্যুপ

ভিতরে if c in text:প্রয়োজন ba?
হ্যাকগুলি

@ হ্যাকস এটি প্রয়োজনীয় নয়, তবে এটির সাথে এটি আরও দ্রুত 2-3x সংক্ষিপ্ত স্ট্রিং, সঙ্গে 1.45 usec per loop, এবং ছাড়া: 5.3 usec per loop, লং স্ট্রিং, সঙ্গে 4.38 usec per loopছাড়া: 7.03 usec per loop। (নোট করুন এগুলি উপরের ফলাফলগুলির সাথে সরাসরি তুলনাযোগ্য নয়, কারণ এটি আলাদা মেশিন ইত্যাদি)
হুগো

1
@Hugo; আমি মনে করি সময় এই পার্থক্য কারণ হল replaceশুধুমাত্র বলা হয় যখন cপাওয়া যায় textক্ষেত্রে baযখন এটি প্রতিটি পুনরাবৃত্তির বলা হয় ab
হ্যাক 14

2
@ হ্যাকস ধন্যবাদ, আমি আমার উত্তরটি আরও সময় দিয়ে আপডেট করেছি: চেক যোগ করা উভয়ের পক্ষে ভাল, তবে সবচেয়ে বড় পাঠ পাইথন 3 হল 3x দ্রুততর!
হুগো

73
>>> string="abc&def#ghi"
>>> for ch in ['&','#']:
...   if ch in string:
...      string=string.replace(ch,"\\"+ch)
...
>>> print string
abc\&def\#ghi

কেন ডাবল ব্যাকস্ল্যাশ দরকার ছিল? শুধু "\" কাজ করে না কেন?
axolotl

3
ডাবল ব্যাকস্ল্যাশ ব্যাকস্ল্যাশ এড়িয়ে যায়, অন্যথায় পাইথন "\" কে স্থির-খোলা স্ট্রিংয়ের মধ্যে আক্ষরিক উদ্ধৃতি চরিত্র হিসাবে ব্যাখ্যা করবে।
রাইট

তোমার দরকার কেন string=string.replace(ch,"\\"+ch)? শুধু কি string.replace(ch,"\\"+ch)যথেষ্ট নয়?
ম্যাটসোম

1
@ ম্যাটসম প্রতিস্থাপন () মূল স্ট্রিংটি পরিবর্তন করে না, তবে একটি অনুলিপি দেয়। সুতরাং কোডটির কোনও প্রভাব ফেলতে আপনার অ্যাসাইনমেন্টের প্রয়োজন।
বেন ব্রায়ান

3
আপনার যদি সত্যিই দরকার হয়? দেখে মনে হচ্ছে এটি প্রতিস্থাপনটি যাইহোক কীভাবে করবে।
লরেঞ্জো

32

কেবল replaceএই মত ফাংশন চেইন

strs = "abc&def#ghi"
print strs.replace('&', '\&').replace('#', '\#')
# abc\&def\#ghi

যদি প্রতিস্থাপনগুলি সংখ্যায় আরও বেশি হতে থাকে, আপনি এই জেনেরিক উপায়ে এটি করতে পারেন

strs, replacements = "abc&def#ghi", {"&": "\&", "#": "\#"}
print "".join([replacements.get(c, c) for c in strs])
# abc\&def\#ghi

29

এখানে পাইথন 3 পদ্ধতি ব্যবহার করে str.translateএবং str.maketrans:

s = "abc&def#ghi"
print(s.translate(str.maketrans({'&': '\&', '#': '\#'})))

মুদ্রিত স্ট্রিং হয় abc\&def\#ghi


2
এটি একটি ভাল উত্তর, তবে অনুশীলনে একটি করা .translate()তিনটি শৃঙ্খলাবদ্ধ .replace()(সিপিথন ৩.6.৪ ব্যবহার করে) চেয়ে ধীর বলে মনে হয় ।
চাঙ্গাকো

@ চ্যাঙ্গাকো সময় নির্ধারণের জন্য ধন্যবাদ practice বাস্তবে আমি replace()নিজেকে ব্যবহার করতাম, তবে আমি এই উত্তরটি সম্পূর্ণতার জন্য যুক্ত করেছি।
tommy.carstensen

বড় স্ট্রিং এবং অনেক প্রতিস্থাপনের জন্য এটি দ্রুত হওয়া উচিত, যদিও কিছু পরীক্ষা ভাল লাগবে ...
গ্রাফার

ভাল, এটি আমার মেশিনে নেই (2 এবং 17 প্রতিস্থাপনের জন্য একই)।
গ্রিফার

কিভাবে '\#'বৈধ? না এটি হওয়া উচিত r'\#'বা '\\#'? একটি কোড ব্লক ফর্ম্যাটিং সমস্যা হতে পারে।
সমতা 3

16

আপনি কি সবসময় একটি ব্যাকস্ল্যাশ প্রিপেন্ড করতে যাচ্ছেন? যদি তাই হয়, চেষ্টা করুন

import re
rx = re.compile('([&#])')
#                  ^^ fill in the characters here.
strs = rx.sub('\\\\\\1', strs)

এটি সবচেয়ে কার্যকর পদ্ধতি নাও হতে পারে তবে আমি মনে করি এটি সবচেয়ে সহজ।


15
আরেঘাঘ চেষ্টাr'\\\1'
জন মাচিন

10

পার্টিতে দেরীতে, তবে আমার উত্তর না পাওয়া পর্যন্ত আমি এই ইস্যুতে অনেক সময় হারাতে পেরেছি।

সংক্ষিপ্ত এবং মিষ্টি, translateশ্রেয়replace । সময়ের অপ্টিমাইজেশানের সাথে আপনি যদি ফানসিওনিয়ালিটির সাথে আরও আগ্রহী হন তবে এটি ব্যবহার করবেন না replace

ব্যবহার translateযদি আপনি যদি অক্ষরের সেট প্রতিস্থাপন করতে ব্যবহৃত অক্ষর সেট ওভারল্যাপ প্রতিস্থাপন করা জানি না।

বিন্দু ক্ষেত্রে:

replaceআপনাকে ব্যবহার করে স্নিপেটটি "1234".replace("1", "2").replace("2", "3").replace("3", "4")ফিরে যাওয়ার প্রত্যাশা করবে "2344", তবে এটি বাস্তবে ফিরে আসবে "4444"

অনুবাদ মূলত ওপি যা পছন্দ করেছে তা সম্পাদন করে বলে মনে হচ্ছে।


6

আপনি জেনেরিক এস্কেপ ফাংশন লেখার বিষয়টি বিবেচনা করতে পারেন:

def mk_esc(esc_chars):
    return lambda s: ''.join(['\\' + c if c in esc_chars else c for c in s])

>>> esc = mk_esc('&#')
>>> print esc('Learn & be #1')
Learn \& be \#1

এই জাতীয় চরিত্রের তালিকা থেকে আপনি পালাতে হবে সেগুলি দিয়ে আপনি আপনার ফাংশনটি কনফিগার করতে পারবেন।


3

এফওয়াইআই, এটি ওপিতে সামান্য বা কোনও উপকারে আসে না তবে এটি অন্য পাঠকদের পক্ষে কার্যকর হতে পারে (দয়া করে ডাউনওয়েট করবেন না, আমি এটি সম্পর্কে সচেতন)।

কিছুটা হাস্যকর কিন্তু আকর্ষণীয় অনুশীলন হিসাবে, আমি দেখতে চেয়েছিলাম যে আমি একাধিক অক্ষর প্রতিস্থাপনের জন্য পাইথন ফাংশনাল প্রোগ্রামিং ব্যবহার করতে পারি কিনা। আমি নিশ্চিত যে এটি কেবলমাত্র কলিং রিপ্লেস () দুটি বার মারবে না pretty এবং যদি পারফরম্যান্সটি কোনও সমস্যা হয়ে থাকে তবে আপনি সহজেই এটি মরিচা, সি, জুলিয়া, পারল, জাভা, জাভাস্ক্রিপ্ট এবং সম্ভবত এমনকি বিশ্রীভাবে পরাজিত করতে পারেন। এটি পাইথোলজ নামে একটি বহিরাগত 'হেল্পার্স' প্যাকেজ ব্যবহার করে , সিথনের মাধ্যমে ত্বরণযুক্ত ( সাইটোল্জ, এটি পাইপি প্যাকেজ )।

from cytoolz.functoolz import compose
from cytoolz.itertoolz import chain,sliding_window
from itertools import starmap,imap,ifilter
from operator import itemgetter,contains
text='&hello#hi&yo&'
char_index_iter=compose(partial(imap, itemgetter(0)), partial(ifilter, compose(partial(contains, '#&'), itemgetter(1))), enumerate)
print '\\'.join(imap(text.__getitem__, starmap(slice, sliding_window(2, chain((0,), char_index_iter(text), (len(text),))))))

আমি এমনকি এটি ব্যাখ্যা করতে যাচ্ছি না কারণ একাধিক প্রতিস্থাপন সম্পন্ন করতে কেউ এটি ব্যবহার করে বিরক্ত করবেন না। তবুও, আমি এটি করতে কিছুটা দক্ষতা অনুভব করেছি এবং ভেবেছিলাম এটি অন্য পাঠকদের অনুপ্রাণিত করতে পারে বা একটি কোড অবলম্বন প্রতিযোগিতা জিততে পারে।


1
"ফাংশনাল প্রোগ্রামিং" এর অর্থ "যতটা সম্ভব ফাংশন ব্যবহার করা" নয়, আপনি জানেন।
ক্রেগ অ্যান্ড্রুজ

1
এটি পুরোপুরি ভাল, খাঁটি কার্যকরী মাল্টি- চোর replacer: gist.github.com/anonymous/4577424f586173fc6b91a215ea2ce89e কোনও বরাদ্দ নেই, কোনও রূপান্তর নেই, কোনও পার্শ্ব প্রতিক্রিয়া নেই। পাঠযোগ্য, খুব।
ক্রেগ অ্যান্ড্রুজ

1

পাইথন 2.7 এবং পাইথন 3 এ যা পাওয়া যায় তা হ্রাস ব্যবহার করে easily

# Lets define a helper method to make it easy to use
def replacer(text, replacements):
    return reduce(
        lambda text, ptuple: text.replace(ptuple[0], ptuple[1]), 
        replacements, text
    )

if __name__ == '__main__':
    uncleaned_str = "abc&def#ghi"
    cleaned_str = replacer(uncleaned_str, [("&","\&"),("#","\#")])
    print(cleaned_str) # "abc\&def\#ghi"

পাইথন ২..7 এ আপনাকে হ্রাস করতে হবে না তবে পাইথন ৩. * আপনাকে এটি ফান্টুলস মডিউল থেকে আমদানি করতে হবে।



1

এ কেমন?

def replace_all(dict, str):
    for key in dict:
        str = str.replace(key, dict[key])
    return str

তারপর

print(replace_all({"&":"\&", "#":"\#"}, "&#"))

আউটপুট

\&\#

উত্তর অনুরূপ


0
>>> a = '&#'
>>> print a.replace('&', r'\&')
\&#
>>> print a.replace('#', r'\#')
&\#
>>> 

কাঁচা স্ট্রিংগুলি ব্যাকস্ল্যাশকে বিশেষভাবে চিকিত্সা না করার জন্য আপনি একটি 'কাঁচা' স্ট্রিং ব্যবহার করতে চান (প্রতিস্থাপনের স্ট্রিং উপসর্গ করে 'r' দ্বারা চিহ্নিত)।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.