अजगर में एक पूर्णांक की लंबाई


232

पायथन में, आप एक पूर्णांक में अंकों की संख्या कैसे पाते हैं?


1
मैं आपके सवाल को नहीं समझता। क्या आपका मतलब पूर्णांक के आकार से है? क्या आप अंकों की संख्या ज्ञात करना चाहते हैं? कृपया स्पष्ट करें।
4

जवाबों:


317

यदि आप पूर्णांक की लंबाई को पूर्णांक में अंकों की संख्या के रूप में चाहते हैं, तो आप हमेशा इसे स्ट्रिंग की तरह परिवर्तित कर सकते हैं str(133)और इसकी लंबाई पा सकते हैं len(str(123))


18
बेशक, यदि आप अंकों की संख्या की तलाश कर रहे हैं, तो यह एक परिणाम उत्पन्न करेगा जो नकारात्मक संख्याओं के लिए बहुत बड़ा है, क्योंकि यह नकारात्मक चिह्न की गणना करेगा।
क्रिस अपचर्च

37
अरे, यह एक धीमा उपाय है। मैंने एक यादृच्छिक 6 अंकों की संख्या का एक भाज्य किया, और इसकी लंबाई पाई। इस विधि में 95.891 सेकंड लगे। और Math.log10विधि केवल 7.486343383789062e-05 सेकंड लगी , लगभग 1501388 बार तेजी से!
फेडकेडर

1
यह सिर्फ धीमा नहीं है, बल्कि अधिक मेमोरी का उपभोग करता है और बड़ी संख्या में परेशानी पैदा कर सकता है। Math.log10इसके बजाय का उपयोग करें ।
पेमैन

245

स्ट्रिंग में रूपांतरण के बिना

import math
digits = int(math.log10(n))+1

शून्य और ऋणात्मक संख्याओं को संभालने के लिए भी

import math
if n > 0:
    digits = int(math.log10(n))+1
elif n == 0:
    digits = 1
else:
    digits = int(math.log10(-n))+2 # +1 if you don't count the '-' 

तुम शायद एक समारोह में रखना चाहते हैं :)

यहाँ कुछ बेंचमार्क हैं। len(str())यहां तक कि काफी कम संख्या के लिए पीछे पहले से ही है

timeit math.log10(2**8)
1000000 loops, best of 3: 746 ns per loop
timeit len(str(2**8))
1000000 loops, best of 3: 1.1 µs per loop

timeit math.log10(2**100)
1000000 loops, best of 3: 775 ns per loop
 timeit len(str(2**100))
100000 loops, best of 3: 3.2 µs per loop

timeit math.log10(2**10000)
1000000 loops, best of 3: 844 ns per loop
timeit len(str(2**10000))
100 loops, best of 3: 10.3 ms per loop

5
इसके लिए log10 का उपयोग करना एक गणितज्ञ का समाधान है; लेन (str ()) का उपयोग करना एक प्रोग्रामर का समाधान है, और स्पष्ट और सरल है।
ग्लेन मेनार्ड

68
@ ग्लेन: मुझे निश्चित रूप से उम्मीद है कि आप इसका मतलब नहीं निकाल रहे हैं कि यह एक बुरा समाधान है। प्रोग्रामर का भोला ओ (लॉग 10 एन) समाधान एड-हॉक, प्रोटोटाइप कोड में अच्छी तरह से काम करता है - लेकिन मैं प्रोडक्शन कोड या सार्वजनिक एपीआई में गणितज्ञ सुरुचिपूर्ण ओ (1) समाधान को बहुत अधिक देखूंगा। Gnibbler के लिए +1।
जूलियट

5
@gnibbler: +1। कभी भी महसूस नहीं किया गया कि किसी संख्या के परिमाण को खोजने के लिए log10 का उपयोग किया जा सकता है। काश मैं एक बार फिर अधिक मतदान कर पाता :)।
अब्बास

14
नमस्ते! मैं कुछ अजीब, आप के कर सकते हैं किसी को भी कृपया मुझे बताएगा कि ऐसा क्यों जाना int(math.log10(x)) +1के लिए 99999999999999999999999999999999999999999999999999999999999999999999999( 71 नौ ) रिटर्न 72 ? मैंने सोचा था कि मैं log10 विधि पर भरोसा कर सकता हूं लेकिन मुझे इसके बजाय len (str (x)) का उपयोग करना होगा :(
Marcky

6
मेरा मानना ​​है कि मुझे अजीब व्यवहार का कारण पता है, यह फ्लोटिंग पॉइंट अशुद्धियों के कारण है। math.log10(999999999999999)के बराबर है 14.999999999999998तो int(math.log10(999999999999999))हो जाता है 14। लेकिन तब math.log10(9999999999999999)के बराबर है 16.0। शायद उपयोग roundकरना इस समस्या का समाधान है।
जामिलाक

43

सभी math.log10 समाधान आपको समस्याएं देंगे।

math.log10 तेज़ है, लेकिन समस्या तब देता है जब आपका नंबर 999999999999997 से अधिक हो। ऐसा इसलिए है क्योंकि फ़्लो में बहुत अधिक .9 s हैं, जिसके परिणामस्वरूप परिणाम गोल हो गया है।

समाधान उस सीमा से ऊपर की संख्या के लिए थोड़ी देर काउंटर विधि का उपयोग करना है।

इसे और भी तेज़ बनाने के लिए, आगे की तरफ 10 ^ 16, 10 ^ 17 बनाएं और एक सूची में चर के रूप में संग्रहीत करें। इस तरह, यह एक टेबल लुकअप की तरह है।

def getIntegerPlaces(theNumber):
    if theNumber <= 999999999999997:
        return int(math.log10(theNumber)) + 1
    else:
        counter = 15
        while theNumber >= 10**counter:
            counter += 1
        return counter

धन्यवाद। यह एक अच्छा प्रति-उदाहरण है math.log10। यह देखना दिलचस्प है कि द्विआधारी प्रतिनिधित्व गणितीय रूप से गलत परिणाम देने वाले मूल्यों को कैसे फ़्लिप करता है।
वल्हू

उसके बाद लेन (str (संख्या)) बेहतर होगी
विघ्नेश राउत

2
@ विघ्नेश राउत: और परिश्रम धीमा
चैतन्य बंगरा

"सटीक परिणाम देने वाले फ्लोटिंग-पॉइंट ऑपरेशंस पर भरोसा करना खतरनाक है" - कोर पिथोन डेवलपमेंट टीम Bugs.python.org/issue3724 के
श्रीरेग एआर

26

अजगर 2.* intरों ले या तो 4 या 8 बाइट्स (32 या 64 बिट्स), अपने अजगर निर्माण पर निर्भर करता है। sys.maxint( 2**31-132-बिट ints के लिए, 2**63-164-बिट ints के लिए) आपको बताएगा कि दोनों में से कौन सी संभावनाएं प्राप्त होती हैं।

पायथन 3 में, ints (जैसे longपायथन 2 में) उपलब्ध स्मृति की मात्रा तक मनमाना आकार ले सकता है; sys.getsizeofआप, किसी भी मूल्य के लिए एक अच्छा संकेत देती है, हालांकि यह है भी कुछ निश्चित अतिरिक्त गिनती:

>>> import sys
>>> sys.getsizeof(0)
12
>>> sys.getsizeof(2**99)
28

यदि, जैसा कि अन्य उत्तर बताते हैं, आप पूर्णांक मान के कुछ स्ट्रिंग प्रतिनिधित्व के बारे में सोच रहे हैं, तो बस lenउस प्रतिनिधित्व का ध्यान रखें, यह आधार 10 या अन्यथा में हो!


क्षमा करें, इस उत्तर को माइनस-एड मिला। यह जानकारीपूर्ण है और प्रश्न के प्रशंसनीय बिंदु पर है (यदि यह केवल अधिक विशिष्ट था जिसके बारे में 'लेन' वांछित है)। +1
mjv

यह दिलचस्प लग रहा है, लेकिन यह निश्चित नहीं है कि लंबाई कैसे निकालें
तजोर्रीमोर्री

17

यह प्रश्न पूछे जाने के बाद कई साल हो गए हैं, लेकिन मैंने एक पूर्णांक की लंबाई की गणना करने के लिए कई तरीकों का एक मानदंड तैयार किया है।

def libc_size(i): 
    return libc.snprintf(buf, 100, c_char_p(b'%i'), i) # equivalent to `return snprintf(buf, 100, "%i", i);`

def str_size(i):
    return len(str(i)) # Length of `i` as a string

def math_size(i):
    return 1 + math.floor(math.log10(i)) # 1 + floor of log10 of i

def exp_size(i):
    return int("{:.5e}".format(i).split("e")[1]) + 1 # e.g. `1e10` -> `10` + 1 -> 11

def mod_size(i):
    return len("%i" % i) # Uses string modulo instead of str(i)

def fmt_size(i):
    return len("{0}".format(i)) # Same as above but str.format

(libc फ़ंक्शन को कुछ सेटअप की आवश्यकता है, जिसे मैंने शामिल नहीं किया है)

size_expब्रायन प्रेस्लोप्स्की के size_strलिए धन्यवाद , GeekTantra के लिए धन्यवाद है, और size_mathजॉन ला रोय के लिए धन्यवाद है

यहाँ परिणाम हैं:

Time for libc size:      1.2204 μs
Time for string size:    309.41 ns
Time for math size:      329.54 ns
Time for exp size:       1.4902 μs
Time for mod size:       249.36 ns
Time for fmt size:       336.63 ns
In order of speed (fastest first):
+ mod_size (1.000000x)
+ str_size (1.240835x)
+ math_size (1.321577x)
+ fmt_size (1.350007x)
+ libc_size (4.894290x)
+ exp_size (5.976219x)

(डिस्क्लेमर: फ़ंक्शन 1 से 1,000,000 तक चलाया जाता है)

यहाँ के लिए परिणाम हैं sys.maxsize - 100000करने के लिए sys.maxsize:

Time for libc size:      1.4686 μs
Time for string size:    395.76 ns
Time for math size:      485.94 ns
Time for exp size:       1.6826 μs
Time for mod size:       364.25 ns
Time for fmt size:       453.06 ns
In order of speed (fastest first):
+ mod_size (1.000000x)
+ str_size (1.086498x)
+ fmt_size (1.243817x)
+ math_size (1.334066x)
+ libc_size (4.031780x)
+ exp_size (4.619188x)

जैसा कि आप देख सकते हैं, mod_size( len("%i" % i)) उपयोग करने की तुलना में सबसे तेज, थोड़ा तेज है str(i)और दूसरों की तुलना में काफी तेज है।


आपको वास्तव में libc setup को शामिल करना चाहिए, libc = ctyle.CDLL('libc.so.6', use_errno=True)(यह है यह अनुमान लगाते हुए)। और यह संख्या से अधिक के लिए काम नहीं करता है sys.maxsizeक्योंकि फ्लोटिंग पॉइंट संख्या "बहुत बड़ी" नहीं हो सकती है। तो ऊपर कोई भी संख्या, मुझे लगता है कि आप धीमी विधियों में से एक के साथ फंस गए हैं।
Torxed

15

संख्या nतब nबताई जाती है, जिसमें अंकों की संख्या दी जाती है:

math.floor(math.log10(n))+1

ध्यान दें कि यह + ve पूर्णांक <10e15 के लिए सही उत्तर देगा। परे कि math.log10kicks के प्रकार की सटीक सीमा में और उत्तर बंद हो सकता है 1. मैं बस len(str(n))उस से परे का उपयोग करेगा ; इसके लिए ऐसे O(log(n))समय की आवश्यकता होती है जो 10 की शक्तियों पर निर्भर हो।

इस सीमा तक मेरी उपस्थिति को लाने के लिए @SetiVolkylany का धन्यवाद। इसका आश्चर्यजनक है कि कैसे सही ढंग से सही समाधान के कार्यान्वयन के विवरण में caveats है।


1
[N -999999999999997, 999999999999997] के बाहर अगर यह काम नहीं करता है
PADYMKO

@SetiVolkylany, मैंने इसे python2.7 और 3.5 के लिए 50 अंकों तक परीक्षण किया। बस एक करो assert list(range(1,51)) == [math.floor(math.log10(n))+1 for n in (10**e for e in range(50))]
BiGYaN

2
इसे Python2.7 या Python3.5 के साथ आज़माएँ >>> math.floor(math.log10(999999999999997))+1 15.0 >>> math.floor(math.log10(999999999999998))+1 16.0। मेरा उत्तर देखो stackoverflow.com/a/42736085/6003870
PADYMKO

12

खैर, स्ट्रिंग में परिवर्तित किए बिना मैं कुछ ऐसा करूंगा:

def lenDigits(x): 
    """
    Assumes int(x)
    """

    x = abs(x)

    if x < 10:
        return 1

    return 1 + lenDigits(x / 10)

न्यूनतावादी पुनरावर्तन एफटीडब्ल्यू


1
आप बड़ी संख्या के लिए पुनरावृत्ति सीमा तक पहुंच जाएंगे।
nog642

9

अंकों की संख्या की गणना w / o एक पूर्णांक को स्ट्रिंग में बदलें:

x=123
x=abs(x)
i = 0
while x >= 10**i:
    i +=1
# i is the number of digits

अच्छा एक स्ट्रिंग रूपांतरण से पूरी तरह से बचा जाता है।
पैट्रिक मुतुकु

7

जैसा कि प्रिय उपयोगकर्ता @Calvintwr ने उल्लेख किया है, फ़ंक्शन math.log10में एक सीमा के बाहर [[-999999999999997, 9999999999997] नंबर पर समस्या है, जहां हमें फ़्लोटिंग पॉइंट त्रुटियां मिलती हैं। मुझे जावास्क्रिप्ट (Google V8 और NodeJS) और C (GNU GCC संकलक) के साथ यह समस्या थी, इसलिए यहाँ एक 'purely mathematically'समाधान असंभव है।


इसके आधार पर सार और जवाब प्रिय उपयोगकर्ता @Calvintwr

import math


def get_count_digits(number: int):
    """Return number of digits in a number."""

    if number == 0:
        return 1

    number = abs(number)

    if number <= 999999999999997:
        return math.floor(math.log10(number)) + 1

    count = 0
    while number:
        count += 1
        number //= 10
    return count

मैंने इसकी संख्या 20 (समावेशी) तक की लंबाई और सभी अधिकार के साथ परीक्षण किया। यह पर्याप्त होना चाहिए, क्योंकि 64-बिट सिस्टम पर लंबाई अधिकतम पूर्णांक संख्या 19 ( len(str(sys.maxsize)) == 19) है।

assert get_count_digits(-99999999999999999999) == 20
assert get_count_digits(-10000000000000000000) == 20
assert get_count_digits(-9999999999999999999) == 19
assert get_count_digits(-1000000000000000000) == 19
assert get_count_digits(-999999999999999999) == 18
assert get_count_digits(-100000000000000000) == 18
assert get_count_digits(-99999999999999999) == 17
assert get_count_digits(-10000000000000000) == 17
assert get_count_digits(-9999999999999999) == 16
assert get_count_digits(-1000000000000000) == 16
assert get_count_digits(-999999999999999) == 15
assert get_count_digits(-100000000000000) == 15
assert get_count_digits(-99999999999999) == 14
assert get_count_digits(-10000000000000) == 14
assert get_count_digits(-9999999999999) == 13
assert get_count_digits(-1000000000000) == 13
assert get_count_digits(-999999999999) == 12
assert get_count_digits(-100000000000) == 12
assert get_count_digits(-99999999999) == 11
assert get_count_digits(-10000000000) == 11
assert get_count_digits(-9999999999) == 10
assert get_count_digits(-1000000000) == 10
assert get_count_digits(-999999999) == 9
assert get_count_digits(-100000000) == 9
assert get_count_digits(-99999999) == 8
assert get_count_digits(-10000000) == 8
assert get_count_digits(-9999999) == 7
assert get_count_digits(-1000000) == 7
assert get_count_digits(-999999) == 6
assert get_count_digits(-100000) == 6
assert get_count_digits(-99999) == 5
assert get_count_digits(-10000) == 5
assert get_count_digits(-9999) == 4
assert get_count_digits(-1000) == 4
assert get_count_digits(-999) == 3
assert get_count_digits(-100) == 3
assert get_count_digits(-99) == 2
assert get_count_digits(-10) == 2
assert get_count_digits(-9) == 1
assert get_count_digits(-1) == 1
assert get_count_digits(0) == 1
assert get_count_digits(1) == 1
assert get_count_digits(9) == 1
assert get_count_digits(10) == 2
assert get_count_digits(99) == 2
assert get_count_digits(100) == 3
assert get_count_digits(999) == 3
assert get_count_digits(1000) == 4
assert get_count_digits(9999) == 4
assert get_count_digits(10000) == 5
assert get_count_digits(99999) == 5
assert get_count_digits(100000) == 6
assert get_count_digits(999999) == 6
assert get_count_digits(1000000) == 7
assert get_count_digits(9999999) == 7
assert get_count_digits(10000000) == 8
assert get_count_digits(99999999) == 8
assert get_count_digits(100000000) == 9
assert get_count_digits(999999999) == 9
assert get_count_digits(1000000000) == 10
assert get_count_digits(9999999999) == 10
assert get_count_digits(10000000000) == 11
assert get_count_digits(99999999999) == 11
assert get_count_digits(100000000000) == 12
assert get_count_digits(999999999999) == 12
assert get_count_digits(1000000000000) == 13
assert get_count_digits(9999999999999) == 13
assert get_count_digits(10000000000000) == 14
assert get_count_digits(99999999999999) == 14
assert get_count_digits(100000000000000) == 15
assert get_count_digits(999999999999999) == 15
assert get_count_digits(1000000000000000) == 16
assert get_count_digits(9999999999999999) == 16
assert get_count_digits(10000000000000000) == 17
assert get_count_digits(99999999999999999) == 17
assert get_count_digits(100000000000000000) == 18
assert get_count_digits(999999999999999999) == 18
assert get_count_digits(1000000000000000000) == 19
assert get_count_digits(9999999999999999999) == 19
assert get_count_digits(10000000000000000000) == 20
assert get_count_digits(99999999999999999999) == 20

पायथन 3.5 के साथ परीक्षण किए गए कोड के सभी उदाहरण


3

पश्चाताप के लिए, इस समस्या का सबसे धीमा समाधान अब तक कोई संदेह नहीं है:

def num_digits(num, number_of_calls=1):
    "Returns the number of digits of an integer num."
    if num == 0 or num == -1:
        return 1 if number_of_calls == 1 else 0
    else:
        return 1 + num_digits(num/10, number_of_calls+1)


1

मान लें कि आप एक पूर्णांक में सबसे बड़ी संख्या के लिए पूछ रहे हैं, तो मूल्य कार्यान्वयन पर निर्भर है। मेरा सुझाव है कि आप अजगर का उपयोग करते समय उस तरह से नहीं सोचते हैं। किसी भी मामले में, एक बड़े मूल्य को अजगर 'पूर्णांक' में संग्रहीत किया जा सकता है। याद रखें, अजगर टाइपिंग का उपयोग करता है!

संपादित करें: मैंने अपना जवाब इस स्पष्टीकरण से पहले दिया कि पूछने वाला अंक की संख्या चाहता था। उसके लिए, मैं स्वीकृत उत्तर द्वारा सुझाई गई विधि से सहमत हूं। जोड़ने के लिए और कुछ नहीं!


1
def length(i):
  return len(str(i))

1

इसका उपयोग करके पूर्णांकों के लिए जल्दी किया जा सकता है:

len(str(abs(1234567890)))

जिसे "1234567890" के निरपेक्ष मान के तार की लंबाई मिलती है

absकिसी भी ऋणात्मक संख्या के बिना संख्या लौटाता है (केवल संख्या की भयावहता), strइसे स्ट्रिंग में परिवर्तित / परिवर्तित करता है और lenउस स्ट्रिंग की स्ट्रिंग लंबाई लौटाता है।

यदि आप चाहते हैं कि यह तैरने के लिए काम करे, तो आप निम्नलिखित में से किसी एक का उपयोग कर सकते हैं:

# Ignore all after decimal place
len(str(abs(0.1234567890)).split(".")[0])

# Ignore just the decimal place
len(str(abs(0.1234567890)))-1

आगामी संदर्भ के लिए।


मुझे लगता है कि intअपने दशमलव स्ट्रिंग प्रतिनिधित्व को कम करने के लिए इनपुट संख्या को स्वयं (उदाहरण के लिए एक कास्ट से ) के रूप में छोटा करना आसान होगा : len(str(abs(int(0.1234567890))))रिटर्न 1.
डेविड फ़ॉस्टर

नहीं, यह काम नहीं करेगा। यदि आप 0.17 को पूर्णांक में बदलते हैं तो आपको 0 प्राप्त होता है और उसकी लंबाई 0.17 की लंबाई से भिन्न होगी
Frogboxe

पहले मामले में, स्ट्रिंग प्रतिनिधित्व से दशमलव बिंदु सहित और सब कुछ ट्रंक करके आप प्रभावी रूप से संख्या के अभिन्न अंग की लंबाई की गणना कर रहे हैं , जो कि मेरा सुझाव भी करता है। 0.17 के लिए दोनों समाधान 1 लौटे।
डेविड फ़ॉस्टर

0

वैज्ञानिक नोटेशन में प्रारूप और घातांक को बंद करें:

int("{:.5e}".format(1000000).split("e")[1]) + 1

मैं गति के बारे में नहीं जानता, लेकिन यह सरल है।

कृपया दशमलव के बाद महत्वपूर्ण अंकों की संख्या पर ध्यान दें। "5।" में "5" एक मुद्दा हो सकता है यदि यह वैज्ञानिक अंकन के दशमलव भाग को दूसरे अंक तक बढ़ाता है। मैंने इसे मनमाने ढंग से बड़ा सेट किया है, लेकिन यह प्रतिबिंबित कर सकता है। आपके बारे में सबसे बड़ी संख्या की लंबाई।


0
def count_digit(number):
  if number >= 10:
    count = 2
  else:
    count = 1
  while number//10 > 9:
    count += 1
    number = number//10
  return count

हालांकि यह कोड प्रश्न को हल कर सकता है, जिसमें यह भी बताया गया है कि यह समस्या कैसे और क्यों हल करती है, इससे वास्तव में आपके पोस्ट की गुणवत्ता को बेहतर बनाने में मदद मिलेगी, और संभवतः अधिक वोटों का परिणाम होगा। याद रखें कि आप भविष्य में पाठकों के लिए प्रश्न का उत्तर दे रहे हैं, न कि केवल उस व्यक्ति से जो अब पूछ रहा है। कृपया स्पष्टीकरण जोड़ने के लिए अपने उत्तर को संपादित करें और संकेत दें कि क्या सीमाएँ और मान्यताएँ लागू होती हैं।
एड्रियन मोल

0

यदि आपको किसी उपयोगकर्ता को इनपुट देने के लिए कहना है और फिर आपको यह गिनना होगा कि कितने नंबर हैं तो आप इसका अनुसरण कर सकते हैं:

count_number = input('Please enter a number\t')

print(len(count_number))

नोट: उपयोगकर्ता इनपुट के रूप में कभी कोई इंट नहीं लें।


एक विशिष्ट मामला जिसे आप यहां वर्णित करते हैं क्योंकि यह वास्तव में एक स्ट्रिंग की लंबाई से संबंधित है। इसके अलावा, मैं किसी भी गैर-संख्यात्मक चरित्र में प्रवेश कर सकता हूं और आपको अभी भी विश्वास होगा कि यह एक संख्या है।
बेन

0
def digits(n)
    count = 0
    if n == 0:
        return 1
    while (n >= 10**count):
        count += 1
        n += n%10
    return count
print(digits(25))   # Should print 2
print(digits(144))  # Should print 3
print(digits(1000)) # Should print 4
print(digits(0))    # Should print 1

0

मेरा कोड इस प्रकार है: मैंने log10 विधि का उपयोग किया है:

from math import *

डिफ_ डिजिट (संख्या):

if number>1 and round(log10(number))>=log10(number) and number%10!=0 :
    return round(log10(number))
elif  number>1 and round(log10(number))<log10(number) and number%10!=0:
    return round(log10(number))+1
elif number%10==0 and number!=0:
    return int(log10(number)+1)
elif number==1 or number==0:
    return 1

मुझे 1 और 0 के मामले में निर्दिष्ट करना था क्योंकि log10 (1) = 0 और log10 (0) = ND और इसलिए उल्लिखित शर्त संतुष्ट है। हालाँकि, यह कोड केवल पूरे नंबर के लिए काम करता है।


0

यहाँ एक तेज़ लेकिन तेज़ संस्करण है:

def nbdigit ( x ):
    if x >= 10000000000000000 : # 17 -
        return len( str( x ))
    if x < 100000000 : # 1 - 8
        if x < 10000 : # 1 - 4
            if x < 100             : return (x >= 10)+1 
            else                   : return (x >= 1000)+3
        else: # 5 - 8                                                 
            if x < 1000000         : return (x >= 100000)+5 
            else                   : return (x >= 10000000)+7
    else: # 9 - 16 
        if x < 1000000000000 : # 9 - 12
            if x < 10000000000     : return (x >= 1000000000)+9 
            else                   : return (x >= 100000000000)+11
        else: # 13 - 16
            if x < 100000000000000 : return (x >= 10000000000000)+13 
            else                   : return (x >= 1000000000000000)+15

बहुत बड़ी संख्या के लिए केवल 5 तुलनाएं। मेरे कंप्यूटर पर यह math.log10संस्करण की तुलना में लगभग 30% तेज और len( str())एक की तुलना में 5% तेज है । ठीक है ... यदि आप इसे उग्र रूप से उपयोग नहीं करते हैं तो कोई आकर्षक नहीं है।

और यहाँ उन संख्याओं का समूह है जो मैंने अपने कार्य का परीक्षण / मापने के लिए उपयोग किया था:

n = [ int( (i+1)**( 17/7. )) for i in xrange( 1000000 )] + [0,10**16-1,10**16,10**16+1]

NB: यह नकारात्मक संख्याओं का प्रबंधन नहीं करता है, लेकिन अनुकूलन आसान है ...


-13
>>> a=12345
>>> a.__str__().__len__()
5

6
विशेष विधियों को सीधे कॉल न करें। जो लिखा हुआ है len(str(a))
माइक ग्राहम

8
@ ghostdog74 सिर्फ इसलिए कि एक बिजली का सॉकेट है, इसका मतलब यह नहीं है कि आपको अपनी उंगलियों को उसमें रखना होगा।

3
इसलिए यदि आप इसके खिलाफ हैं, तो आप मुझे यह क्यों नहीं बताते कि इसका उपयोग करने में क्या गलत है?
ghostdog74

11
"मैजिक" __ पद्धतियां पायथन इंटर्न के लिए वापस कॉल करने के लिए हैं, आपके कोड को सीधे कॉल करने के लिए नहीं। यह हॉलीवुड फ्रेमवर्क पैटर्न है: हमें कॉल न करें, हम आपको कॉल करेंगे। लेकिन इस ढांचे का आशय यह है कि ये मानक पायथन के लिए जादू की विधियां हैं, जिनका उपयोग करने के लिए बिल्ट-इन बनाया गया है, ताकि आपका वर्ग बिल्ट-इन के व्यवहार को अनुकूलित कर सके। यदि यह आपके कोड को सीधे कॉल करने के लिए एक विधि है, तो विधि को एक गैर - "__" नाम दें। यह उन तरीकों को स्पष्ट रूप से अलग करता है जो प्रोग्रामर खपत के लिए अभिप्रेत हैं, बनाम जो कि पायथन द्वारा निर्मित कॉलबैक के लिए प्रदान किए गए हैं।
पॉलएमसीजी

7
यह एक बुरा विचार है क्योंकि ज्ञात ब्रह्मांड में हर कोई str () और len () का उपयोग करता है। यह अलग होने के लिए अलग है, जो स्वाभाविक रूप से एक बुरी बात है - यह उल्लेख करने के लिए नहीं है कि यह नरक के रूप में बदसूरत है। -1।
ग्लेन मेनार्ड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.