পাইথন লেজ পুনরাবৃত্তি অনুকূলিত করে?


205

আমার কাছে নিম্নোক্ত কোডের টুকরা রয়েছে যা নিম্নলিখিত ত্রুটির সাথে ব্যর্থ হয়:

রানটাইময়েরর: সর্বাধিক পুনরাবৃত্তির গভীরতা অতিক্রম করেছে

লেজ পুনরাবৃত্তি অপ্টিমাইজেশনের (টিসিও) অনুমতি দেওয়ার জন্য আমি এটি পুনরায় লেখার চেষ্টা করেছি। আমি বিশ্বাস করি যে টিসিও হয়ে থাকলে এই কোডটি সফল হওয়া উচিত ছিল should

def trisum(n, csum):
    if n == 0:
        return csum
    else:
        return trisum(n - 1, csum + n)

print(trisum(1000, 0))

আমার কি এই উপসংহারে আসা উচিত যে পাইথন কোনও প্রকারের টিসিও করে না, বা আমার কেবল এটি আলাদাভাবে সংজ্ঞায়িত করা দরকার?


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

11
ওহ, একটি নীটপিক: আপনি লেজ পুনরাবৃত্তি সম্পর্কে একচেটিয়াভাবে কথা বলুন, তবে "টিসিও" সংক্ষিপ্ত শব্দটি ব্যবহার করুন, যার অর্থ লেজ কল অপ্টিমাইজেশন এবং এটি পুনরাবৃত্তিযোগ্য কিনা তা কোনও ক্ষেত্রেই return func(...)(স্পষ্টভাবে বা স্পষ্টতই) প্রয়োগ হয় । টিসিও হ'ল টিআরই-এর যথাযথ সুপারসেট, এবং আরও দরকারী (যেমন এটি ধারাবাহিকভাবে পাস করার শৈলীকে সম্ভব করে তোলে, যা টিআরই করতে পারে না), এবং প্রয়োগ করা খুব বেশি কঠিন নয়।

1
এটি কার্যকর করার জন্য এখানে একটি হ্যাকিশ উপায় - একটি সজ্জনকারী
jsbueno

2
আপনি যদি নিজেকে লেজ পুনরাবৃত্তিতে সীমাবদ্ধ রাখেন তবে আমি মনে করি না যে সঠিক ট্রেসব্যাকটি অতি কার্যকর। আপনার কাছে কল fooথেকে ভিতরে থেকে ভিতরে কল করার fooজন্য fooএকটি কল আছে foo... আমার মনে হয় না যে কোনও দরকারী তথ্য এটি হারাতে গেলে হারিয়ে যাবে।
কেভিন

1
আমি সম্প্রতি নারকেল সম্পর্কে জেনেছি কিন্তু এখনও চেষ্টা করে দেখিনি । এটি একবার দেখে নেওয়া মূল্যবান। এটি টেল রিকার্সন অপ্টিমাইজেশন রয়েছে বলে দাবি করা হচ্ছে।
আলেক্সি

উত্তর:


214

না, এবং যেহেতু গিডো ভ্যান রসুম সঠিক ট্রেসব্যাকগুলি রাখতে সক্ষম হওয়া পছন্দ করে:

লেজ পুনরাবৃত্তি নির্মূল (2009-04-22)

টেল কলগুলিতে চূড়ান্ত শব্দ (২০০৯-০৪-২7)

আপনি ম্যানুয়ালি এই জাতীয় পরিবর্তনের মাধ্যমে পুনরাবৃত্তিটি মুছে ফেলতে পারেন:

>>> def trisum(n, csum):
...     while True:                     # Change recursion to a while loop
...         if n == 0:
...             return csum
...         n, csum = n - 1, csum + n   # Update parameters instead of tail recursion

>>> trisum(1000,0)
500500

12
বা আপনি যদি এটির মতো রূপান্তর করতে চলেছেন - ঠিক from operator import add; reduce(add, xrange(n + 1), csum):?
জন ক্লিমেটস

38
@ জোনক্লিমেন্টস, যা এই বিশেষ উদাহরণে কাজ করে। কিছুক্ষণের লুপে রূপান্তর সাধারন ক্ষেত্রে লেজ পুনরাবৃত্তির জন্য কাজ করে।
জন লা রুই

25
+1 সঠিক উত্তর হওয়ার জন্য তবে এটি অবিশ্বাস্যভাবে হাড়-মাথাযুক্ত ডিজাইনের সিদ্ধান্তের মতো বলে মনে হচ্ছে। প্রদত্ত কারণে নিচে ফোঁড়া থেকে "এটা কিভাবে পাইথন ব্যাখ্যা করা হয় দেওয়া কঠিন এবং আমি তাই যাহাই হউক না কেন এটা পছন্দ করবেন না!" বলে মনে হচ্ছে
বেসিক

12
@jwg তাই ... কি? দুর্বল ডিজাইনের সিদ্ধান্ত নিয়ে মন্তব্য করার আগে আপনাকে কোন ভাষা লিখতে হবে? যুক্তিযুক্ত বা ব্যবহারিক মনে হয় না। আমি আপনার মন্তব্য থেকে ধরে নিলাম যে কোনও ভাষায় রচিত কোনও বৈশিষ্ট্য (বা এর অভাব) সম্পর্কে আপনার কোনও মতামত নেই?
বেসিক

2
@ বেসিক না, তবে আপনি যে নিবন্ধটি মন্তব্য করছেন তা আপনাকে পড়তে হবে। এটি খুব দৃ strongly়রূপে মনে হয় যে আপনি এটি পড়েননি, কীভাবে আপনার কাছে এটি "ফুটে যায়" considering (আপনাকে সম্ভবত লিঙ্কযুক্ত উভয় প্রবন্ধই পড়তে হবে, দুর্ভাগ্যক্রমে, যেহেতু উভয় পক্ষেই কিছু যুক্তি ছড়িয়ে রয়েছে।) ভাষার বাস্তবায়নের সাথে এর প্রায় কিছুই করার নেই, তবে উদ্দেশ্যযুক্ত শব্দার্থবিদ্যার সাথে সবকিছু করার জন্য।
ভিকি

178

আমি টেল-কল অপ্টিমাইজেশন (লেজ-পুনরাবৃত্তি এবং ধারাবাহিকতা-পাসিং শৈলী উভয় পরিচালনা করে) সম্পাদনা করে একটি মডিউল প্রকাশ করেছি: https://github.com/baruchel/tco

পাইথনে লেজ-পুনরাবৃত্তির অনুকূলকরণ

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

পাইথনে লেজ-পুনরাবৃত্তির অপ্টিমাইজ করা আসলে বেশ সহজ। যদিও এটি অসম্ভব বা খুব কৃপণ বলে মনে হচ্ছে, আমি মনে করি এটি মার্জিত, সংক্ষিপ্ত এবং সাধারণ সমাধান দিয়ে অর্জন করা যেতে পারে; আমি এমনকি মনে করি যে এই সমাধানগুলির বেশিরভাগটি পাইথন বৈশিষ্ট্যগুলি ব্যবহার করা উচিত নয় otherwise খুব স্ট্যান্ডার্ড লুপের সাথে পরিচ্ছন্ন ল্যাম্বদা এক্সপ্রেশনগুলি লেজ-পুনরাবৃত্তি অপ্টিমাইজেশান বাস্তবায়নের জন্য দ্রুত, দক্ষ এবং সম্পূর্ণরূপে ব্যবহারযোগ্য সরঞ্জামের দিকে পরিচালিত করে।

একটি ব্যক্তিগত সুবিধার্থে, আমি দুটি ভিন্ন উপায়ে যেমন একটি অপ্টিমাইজেশন প্রয়োগ করে একটি ছোট মডিউল লিখেছিলাম। আমি আমার দুটি প্রধান কার্যাদি সম্পর্কে এখানে আলোচনা করতে চাই।

পরিষ্কার উপায়: ওয়াই সংযুক্তকারীকে সংশোধন করা

ওয়াই combinator সুপরিচিত হয়; এটি একটি পুনরাবৃত্ত পদ্ধতিতে ল্যাম্বদা ফাংশনগুলি ব্যবহার করতে দেয় তবে এটি নিজেই কোনও লুপে পুনরাবৃত্ত কলগুলি এম্বেড করার অনুমতি দেয় না। ল্যাম্বদা ক্যালকুলাস একাই এ জাতীয় কাজ করতে পারে না। ওয়াই কম্বিনেটরে সামান্য পরিবর্তন তবে প্রকৃত মূল্যায়নের জন্য পুনরাবৃত্ত কলকে সুরক্ষা দিতে পারে। মূল্যায়ন এইভাবে বিলম্ব হতে পারে।

ওয়াই সংযুক্তকারীটির জন্য এখানে বিখ্যাত অভিব্যক্তিটি রয়েছে:

lambda f: (lambda x: x(x))(lambda y: f(lambda *args: y(y)(*args)))

খুব সামান্য পরিবর্তন সহ, আমি পেতে পারি:

lambda f: (lambda x: x(x))(lambda y: f(lambda *args: lambda: y(y)(*args)))

নিজেকে কল করার পরিবর্তে, ফাংশনটি এখন একই कॉल সম্পাদন করে একটি ফাংশন ফিরিয়ে দেয়, তবে যেহেতু এটি এটি ফেরত দেয়, পরে মূল্যায়ন বাইরে থেকে করা যায়।

আমার কোডটি হ'ল:

def bet(func):
    b = (lambda f: (lambda x: x(x))(lambda y:
          f(lambda *args: lambda: y(y)(*args))))(func)
    def wrapper(*args):
        out = b(*args)
        while callable(out):
            out = out()
        return out
    return wrapper

ফাংশনটি নিম্নলিখিত উপায়ে ব্যবহার করা যেতে পারে; ফ্যাটোরিয়াল এবং ফিবোনাকির লেজ-পুনরাবৃত্ত সংস্করণের দুটি উদাহরণ এখানে রয়েছে:

>>> from recursion import *
>>> fac = bet( lambda f: lambda n, a: a if not n else f(n-1,a*n) )
>>> fac(5,1)
120
>>> fibo = bet( lambda f: lambda n,p,q: p if not n else f(n-1,q,p+q) )
>>> fibo(10,0,1)
55

স্পষ্টতই পুনরাবৃত্তি গভীরতা কোনও সমস্যা নয়:

>>> bet( lambda f: lambda n: 42 if not n else f(n-1) )(50000)
42

এটি অবশ্যই ফাংশনের একক আসল উদ্দেশ্য।

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

এই প্রক্রিয়াটির গতি সম্পর্কে (যা তবে আসল সমস্যা নয়) এটি বেশ ভাল বলে মনে হয়; লেজ-পুনরাবৃত্তি ফাংশন এমনকি সহজ এক্সপ্রেশন ব্যবহার করে নিম্নলিখিত কোডের তুলনায় অনেক দ্রুত মূল্যায়ন করা হয়:

def bet1(func):
    def wrapper(*args):
        out = func(lambda *x: lambda: x)(*args)
        while callable(out):
            out = func(lambda *x: lambda: x)(*out())
        return out
    return wrapper

আমি মনে করি যে একটি এক্সপ্রেশন মূল্যায়ন, এমনকি জটিল, বেশ কয়েকটি সহজ অভিব্যক্তি মূল্যায়নের চেয়েও দ্রুততর, যা এই দ্বিতীয় সংস্করণের ক্ষেত্রে। আমি এই নতুন ফাংশনটি আমার মডিউলটিতে রাখি নি এবং "অফিসিয়াল" না করে এটি ব্যবহার করার মতো কোনও পরিস্থিতি আমি দেখতে পাই না।

ব্যতিক্রম সহ ধারাবাহিকতা পাস করার শৈলী

এখানে আরও সাধারণ ফাংশন রয়েছে; এটি অন্যান্য ফাংশনগুলি ফিরিয়ে নেওয়া সহ সমস্ত পুচ্ছ-পুনরাবৃত্ত ফাংশনগুলি পরিচালনা করতে সক্ষম। পুনরাবৃত্ত কলগুলি ব্যতিক্রমগুলির ব্যবহারের মাধ্যমে অন্যান্য রিটার্ন মানগুলি থেকে স্বীকৃত। এই সমাধানগুলি আগেরটির চেয়ে ধীর; প্রধান লুপটিতে "পতাকাগুলি" সনাক্ত করা হিসাবে কিছু বিশেষ মান ব্যবহার করে একটি দ্রুত কোড সম্ভবত রচনা করা যেতে পারে তবে আমি বিশেষ মান বা অভ্যন্তরীণ কীওয়ার্ডগুলি ব্যবহার করার ধারণা পছন্দ করি না। ব্যতিক্রমগুলি ব্যবহার করার কিছু মজার ব্যাখ্যা রয়েছে: পাইথন যদি লেজ-পুনরাবৃত্ত কলগুলি পছন্দ না করে, একটি লেজ পুনরাবৃত্তি কল আসে তখন একটি ব্যতিক্রম উত্থাপন করা উচিত এবং কিছু পরিষ্কার খুঁজে পেতে পাইথোনিক উপায়টি ব্যতিক্রমটি ধরা হবে be সমাধান, যা আসলে এখানে ঘটে ...

class _RecursiveCall(Exception):
  def __init__(self, *args):
    self.args = args
def _recursiveCallback(*args):
  raise _RecursiveCall(*args)
def bet0(func):
    def wrapper(*args):
        while True:
          try:
            return func(_recursiveCallback)(*args)
          except _RecursiveCall as e:
            args = e.args
    return wrapper

এখন সমস্ত ফাংশন ব্যবহার করা যেতে পারে। নিম্নলিখিত উদাহরণে, f(n)এন এর যে কোনও ধনাত্মক মানের জন্য পরিচয় ফাংশনটিতে মূল্যায়ন করা হয়:

>>> f = bet0( lambda f: lambda n: (lambda x: x) if not n else f(n-1) )
>>> f(5)(42)
42

অবশ্যই, এটি যুক্তিযুক্ত হতে পারে যে ব্যতিক্রমগুলি ইচ্ছাকৃতভাবে দোভাষীকে পুনঃনির্দেশের জন্য ব্যবহার করার উদ্দেশ্যে নয় (এক ধরণের gotoবিবৃতি বা সম্ভবত বরং এক ধরণের ধারাবাহিকতা পাস করার শৈলী হিসাবে), যা আমাকে স্বীকার করতে হবে। তবে, আবারও আমি tryএকক লাইনটি returnবিবৃতি হিসাবে ব্যবহার করার ধারণাটি মজাদার বলে মনে করি: আমরা কিছু (স্বাভাবিক আচরণ) ফিরিয়ে দেওয়ার চেষ্টা করি তবে পুনরাবৃত্তির কল (ব্যতিক্রম) হওয়ার কারণে আমরা তা করতে পারি না।

প্রাথমিক উত্তর (2013-08-29)।

লেজ পুনরাবৃত্তি পরিচালনা করার জন্য আমি একটি খুব ছোট প্লাগইন লিখেছি। আপনি এখানে আমার ব্যাখ্যা সহ এটি পেতে পারেন: https://groups.google.com/forum/?hl=fr#!topic/comp.lang.python/dIsnJ2BoBKs

এটি অন্য ফাংশনে লেজ পুনরাবৃত্ত শৈলীর সাথে লিখিত একটি ল্যাম্বডা ফাংশন এম্বেড করতে পারে যা এটি লুপ হিসাবে মূল্যায়ন করবে।

এই ছোট ফাংশনের সবচেয়ে আকর্ষণীয় বৈশিষ্ট্যটি, আমার বিনীত মতে এটি হ'ল ফাংশনটি কিছু নোংরা প্রোগ্রামিং হ্যাকের উপর নির্ভর করে না তবে কেবল ল্যাম্বডা ক্যালকুলাসের উপর নির্ভর করে: অন্য ল্যাম্বডা ফাংশনে whenোকানো হলে ফাংশনের আচরণটি অন্যটিতে পরিবর্তিত হয় which Y কম্বিনেটরের মতো দেখতে খুব ভাল লাগে।


আপনি কি দয়া করে কোনও ফাংশন সংজ্ঞায়নের উদাহরণ প্রদান করতে পারেন (সাধারণত কোনও সাধারণ সংজ্ঞাটির অনুরূপ) যা আপনার পদ্ধতিটি ব্যবহার করে কোনও শর্তের উপর ভিত্তি করে অন্য কয়েকটি ফাংশনগুলির মধ্যে একটিতে লেজ-কল করে? এছাড়াও, আপনার মোড়ক ফাংশনটি bet0শ্রেণিবদ্ধ পদ্ধতিগুলির জন্য সজ্জা হিসাবে ব্যবহার করা যেতে পারে?
অ্যালেক্সি

@ অ্যালেক্সি আমি নিশ্চিত নই যে আমি একটি মন্তব্যের ভিতরে ব্লক-স্টাইলে কোড লিখতে পারি, তবে আপনি অবশ্যই defআপনার ফাংশনগুলির জন্য বাক্য গঠন ব্যবহার করতে পারেন এবং উপরের শেষ উদাহরণটি একটি শর্তের উপর নির্ভর করে। আমার পোস্টে বারুচেল.github.io/python/2015/11/07/… আপনি " অনুগ্রহ করে আপত্তি করতে পারেন যে কেউ এই ধরনের কোড লিখবেন না" দিয়ে শুরু করে একটি প্যারা দেখতে পাবেন যেখানে আমি সাধারণ সংজ্ঞা বাক্য গঠন সহ একটি উদাহরণ দিই। আপনার প্রশ্নের দ্বিতীয় অংশের জন্য, আমাকে এটি সম্পর্কে আরও কিছুদূর ভাবতে হবে যেহেতু আমি এতে কিছুক্ষণ সময় কাটিয়েছি না। শুভেচ্ছা।
থমাস বারুচেল

আপনি যদি টিসিও-বহির্ভুত ভাষা প্রয়োগ না করে থাকেন তবে আপনার ফাংশনে কোথায় পুনরাবৃত্ত কল হবে তা আপনার যত্ন নেওয়া উচিত। এটি কারণ কারণ পুনরাবৃত্তি কল পরে ফাংশন যে অংশটি ঘটে সে অংশটি স্ট্যাকের মধ্যে সঞ্চয় করা দরকার। অতএব, আপনার ফাংশনটি টেল-রিরসিভ করে তুলনামূলকভাবে আপনাকে পুনরাবৃত্ত কল অনুযায়ী যে পরিমাণ তথ্য সঞ্চয় করতে হবে তা হ্রাস করে, যা আপনার যদি প্রয়োজন হয় তবে বড় পুনরাবৃত্ত কল স্ট্যাকের জন্য আরও বেশি জায়গা দেয়।
জোসিয়াহ

21

গাইডের শব্দটি http://neopythonic.blogspot.co.uk/2009/04/tail-recursion-elimination.html এ রয়েছে

আমি পাইথনের কার্যকরী বৈশিষ্ট্যগুলির উত্স সম্পর্কে আমার পাইথন ইতিহাস ব্লগে সম্প্রতি একটি এন্ট্রি পোস্ট করেছি। পুচ্ছ পুনরাবৃত্তি নির্মূলকরণ (টিআরই) সমর্থন না করার বিষয়ে এক পক্ষের মন্তব্যটি সাথে সাথে বিভিন্ন মন্তব্য প্রকাশ করেছিল যে পাইথন এটি করছে না, অন্যরা যে "প্রমাণ" করার চেষ্টা করছে যে পাইথনটিতে টিআরই যোগ করা যেতে পারে তার সাম্প্রতিক ব্লগ এন্ট্রিগুলির লিঙ্কগুলি সহ এটি করা হয় না সহজে। সুতরাং আমাকে আমার অবস্থানটি রক্ষা করুন (যা আমি ভাষায় টিআরই চাই না)। যদি আপনি একটি সংক্ষিপ্ত উত্তর চান, এটি কেবল অযৌক্তিক। এখানে দীর্ঘ উত্তর:


12
এবং এর মধ্যে তথাকথিত বিডিএসএফএল সমস্যা রয়েছে।
অ্যাডাম ডোনাহু

6
@ অ্যাডামডোনাহু কোন কমিটি থেকে আসা প্রতিটি সিদ্ধান্ত নিয়ে আপনি পুরোপুরি সন্তুষ্ট? কমপক্ষে আপনি বিডিএফএল থেকে যুক্তিযুক্ত এবং অনুমোদনমূলক ব্যাখ্যা পাবেন।
মার্ক

2
না, অবশ্যই তা নয়, তবে তারা আমাকে আরও সমাহারিত করে strike এটি কোনও প্রেসক্রিটিভিস্টের কাছ থেকে, কোনও ডেস্ক্রিপটিভিস্ট নয়। পরিহাস.
অ্যাডাম ডোনাহু

6

সিপিথন এই বিষয়ে গাইডো ভ্যান রসমের বক্তব্যের ভিত্তিতে টেল কল অপটিমাইজেশন সমর্থন করে না এবং সম্ভবত কখনও সমর্থন করে না ।

আমি যুক্তি শুনেছি যে এটি স্ট্যাক ট্রেসকে কীভাবে সংশোধন করে তা ডিবাগিংকে আরও কঠিন করে তোলে।


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


2

লেজ পুনরাবৃত্তি অপ্টিমাইজ করার পাশাপাশি, আপনি নিজে থেকে পুনরাবৃত্তি গভীরতা সেট করতে পারেন:

import sys
sys.setrecursionlimit(5500000)
print("recursion limit:%d " % (sys.getrecursionlimit()))

5
আপনি কেবল jQuery ব্যবহার করবেন না কেন?
জেরেমি হার্ট

5
কারণ এছাড়াও TCO অফার করে না? :-D stackoverflow.com/questions/3660577/...
Veky
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.