एक ही लाइन पर प्रिंट करें और अजगर में एक नई लाइन नहीं


85

मूल रूप से मैं इसके विपरीत करना चाहता हूं कि इस आदमी ने क्या किया ... हेहे।

पाइथन स्क्रिप्ट: मौजूदा लाइन को अपडेट करने के बजाय हर बार नई लाइन प्रिंट करें

मेरा एक कार्यक्रम है जो मुझे बता रहा है कि यह कितना दूर है।

for i in some_list:
    #do a bunch of stuff.
    print i/len(some_list)*100," percent complete"

तो अगर len (some_list) 50 थी, तो मुझे लगता है कि अंतिम पंक्ति 50 बार से अधिक मुद्रित होगी। मैं एक लाइन प्रिंट करना चाहता हूं और उस लाइन को अपडेट करता रहता हूं। मुझे पता है कि मुझे पता है कि यह शायद सबसे कठिन सवाल है जो आप पूरे दिन पढ़ेंगे। मैं सिर्फ उन चार शब्दों का पता नहीं लगा सकता जो मुझे उत्तर पाने के लिए Google में डालने की आवश्यकता है।

अपडेट करें! मैंने mvds के सुझाव को आज़माया जो सही लगा। नया कोड

print percent_complete,"           \r",

प्रतिशत पूर्ण सिर्फ एक स्ट्रिंग है (मैं पहली बार सार कर रहा था अब मैं शाब्दिक होने की कोशिश कर रहा हूं)। अब परिणाम यह है कि यह कार्यक्रम चलाता है, कार्यक्रम समाप्त होने तक कुछ भी प्रिंट नहीं करता है, और फिर एक और केवल एक लाइन पर "100 प्रतिशत पूर्ण" प्रिंट करता है।

गाड़ी वापसी के बिना (लेकिन अल्पविराम के साथ, mvds 'सुझाव के आधे) यह अंत तक कुछ भी नहीं छापता है। और फिर प्रिंट:

0 percent complete     2 percent complete     3 percent complete     4 percent complete    

और इसी तरह। तो अब नया मुद्दा यह है कि अल्पविराम के साथ यह तब तक प्रिंट नहीं होता है जब तक कि कार्यक्रम समाप्त नहीं हो जाता है।

गाड़ी वापसी के साथ और कोई अल्पविराम के साथ ऐसा ही व्यवहार करता है।


आप यह भी जांचना चाह सकते हैं कि sys.stdout.isatty()जब आप टर्मिनल में नहीं चल रहे हैं तो इन चीजों को बाहर न थूकें।
mvds

मैं इसे एक टर्मिनल से चला रहा हूं ... हालांकि अच्छा सोचा। मुझे यकीन है कि मुझे कुछ बिंदु पर इसकी आवश्यकता होगी।
क्रिस्चौली

1
पृष्ठभूमि है, btw, कि कई भाषाओं में \ n (जो अब हम चूक जाते हैं) स्टडआउट को फ्लश करने के लिए एक अंतर्निहित संकेत के रूप में कार्य करता है। अन्यथा बहुत सारे लोग भ्रमित होंगे।
mvds

जवाबों:


85

इसे गाड़ी वापसी कहा जाता है, या \r

उपयोग

print i/len(some_list)*100," percent complete         \r",

अल्पविराम प्रिंट को नई पंक्ति में जोड़ने से रोकता है। (और रिक्त स्थान लाइन को पूर्व आउटपुट से स्पष्ट रखेंगे)

इसके अलावा, print ""कम से कम एक अंतिम रूप देने वाली न्यूलाइन प्राप्त करने के लिए इसे समाप्त करना न भूलें !


12
बस सुनिश्चित करें कि आप हमेशा लाइन में डेटा (या किसी पिछले प्रिंट से अधिक) की एक ही राशि प्रिंट कर रहे हैं, अन्यथा आप अंत में cruft के साथ समाप्त हो जाएंगे।
निकोलस नाइट

इतना करीब ... मैं इस के परिणाम के साथ सवाल का अद्यतन करेंगे।
क्रिस्चौली

2
@ डस्टिनैचोस: हे, उस शिकन के बारे में भूल गया। पायथन आउटपुट बफ़रिंग प्रश्न देखें: stackoverflow.com/questions/107705/python-output-buffering
निकोलस नाइट

1
@dustynachos: (या प्रत्येक प्रिंट कॉल के बाद sys.stdout.flush () का उपयोग करें, यह वास्तव में बेहतर हो सकता है यदि आप अपने बाकी के कार्यक्रम के लिए आउटपुट बफ़रिंग की परवाह नहीं करते हैं)
निकोलस नाइट

2
यह मेरे लिए काम नहीं करता है। मैंने वास्तव में कई बार यह कोशिश की है और यह मेरे लिए कभी काम नहीं किया है। मैं iterm2 का उपयोग कर रहा हूँ MAC, लेकिन मैं एक linux सर्वर में सबसे अधिक समय ssh'd है। मुझे ऐसा करने का तरीका कभी नहीं मिला जो वास्तव में काम करता हो।
bgenchel

35

मेरे लिए, रेमी और सीरियस के जवाबों का एक कॉम्बो क्या था:

from __future__ import print_function
import sys

print(str, end='\r')
sys.stdout.flush()

33

अजगर 3.x से आप कर सकते हैं:

print('bla bla', end='')

(जिसे from __future__ import print_functionआपकी स्क्रिप्ट / मॉड्यूल के शीर्ष पर रखकर पायथन 2.6 या 2.7 में भी उपयोग किया जा सकता है )

पायथन कंसोल प्रोग्रेसबार उदाहरण:

import time

# status generator
def range_with_status(total):
    """ iterate from 0 to total and show progress in console """
    n=0
    while n<total:
        done = '#'*(n+1)
        todo = '-'*(total-n-1)
        s = '<{0}>'.format(done+todo)
        if not todo:
            s+='\n'        
        if n>0:
            s = '\r'+s
        print(s, end='')
        yield n
        n+=1

# example for use of status generator
for i in range_with_status(10):
    time.sleep(0.1)

The \ r एक नई पंक्ति को जोड़ने के लिए प्रकट होता है
fccoelho

2
यह न्यूलाइन से छुटकारा दिलाता है, लेकिन ओवरराइटिंग की अनुमति नहीं देता है, जो मुझे लगता है कि लेखक क्या चाहता है।
bgenchel

1
@bgenchel '\ r' (कोड नमूने में) के साथ प्रयोग किया जाता है, यह वही करता है जो ओपी चाहता है
मिलो विलोन्डेक

19

पायथन 3.3+ में आपको ज़रूरत नहीं है sys.stdout.flush()print(string, end='', flush=True)काम करता है।

इसलिए

print('foo', end='')
print('\rbar', end='', flush=True)

'बार' के साथ 'फू' को अधिलेखित करेगा।


2
यह काम करता है, बशर्ते मुद्रित पाठ एक के साथ समाप्त होता है "\r"
bli

13

कंसोल के लिए आपको संभवतः आवश्यकता होगी

sys.stdout.flush()

अद्यतन करने के लिए मजबूर करने के लिए। मुझे लगता है कि ,प्रिंट का उपयोग फ्लशिंग से स्टडआउट को अवरुद्ध करेगा और किसी तरह यह अपडेट नहीं होगा


टर्मिनेटर मेरे लिए प्रिंट ("...", अंत = '\ r') का उपयोग करते हुए हर 30 सेकंड पर केवल पंक्ति को ताज़ा कर रहा था जब तक कि मैं प्रिंट स्टेटमेंट के तुरंत बाद इस कमांड को नहीं चलाता। धन्यवाद
ब्राइस Guinta

4

खेल के लिए देर से - लेकिन जब से कोई भी उत्तर मेरे लिए काम नहीं किया (मैंने उन सभी की कोशिश नहीं की) और मैं अपनी खोज में एक से अधिक बार इस उत्तर पर आया हूं ... अजगर 3 में, यह समाधान बहुत सुंदर है और मेरा मानना ​​है कि लेखक वही खोज रहा है, जो एक ही लाइन पर एक स्टेटमेंट को अपडेट करता है। ध्यान दें, यदि लाइन बढ़ने के बजाय सिकुड़ती है, तो आपको कुछ विशेष करना पड़ सकता है (जैसे शायद स्ट्रिंग को अंत में गद्देदार स्थानों के साथ एक निश्चित लंबाई बनाते हैं)

if __name__ == '__main__':
    for i in range(100):
        print("", end=f"\rPercentComplete: {i} %")
        time.sleep(0.2)

अजगर के लिए सबसे सरल और साफ विकल्प => 3.6
डेवआर

3

यह मेरे लिए काम करता है, यह देखने के लिए एक बार हैक किया कि क्या यह संभव है, लेकिन वास्तव में मेरे कार्यक्रम में कभी इस्तेमाल नहीं किया गया (जीयूआई इतना शाब्दिक है:

import time
f = '%4i %%'
len_to_clear = len(f)+1
clear = '\x08'* len_to_clear
print 'Progress in percent:'+' '*(len_to_clear),
for i in range(123):
    print clear+f % (i*100//123),
    time.sleep(0.4)
raw_input('\nDone')

2
import time
import sys


def update_pct(w_str):
    w_str = str(w_str)
    sys.stdout.write("\b" * len(w_str))
    sys.stdout.write(" " * len(w_str))
    sys.stdout.write("\b" * len(w_str))
    sys.stdout.write(w_str)
    sys.stdout.flush()

for pct in range(0, 101):
    update_pct("{n}%".format(n=str(pct)))
    time.sleep(0.1)

\bकर्सर के स्थान को एक स्थान पीछे ले जाएगा
इसलिए हम इसे पंक्ति के आरंभ में वापस ले जाते हैं। हम
वर्तमान लाइन को खाली करने के लिए रिक्त स्थान लिखते हैं - जैसे ही हम रिक्त स्थान लिखते हैं कर्सर एक / एक करके आगे बढ़ता है।
तो हम अपना नया डेटा लिखने से पहले कर्सर को लाइन की शुरुआत में वापस ले जाएं

पायथन 2.7 का उपयोग करके विंडोज cmd पर परीक्षण किया गया


1

इसे इस तरह आज़माएँ:

for i in some_list:
    #do a bunch of stuff.
    print i/len(some_list)*100," percent complete",

(अंत में एक अल्पविराम के साथ।)


यह सिर्फ पुराने (कार्यात्मक रूप से लेकिन बदसूरत) के लिए नए पाठ को जोड़ता है।
क्रिसचौली

1

यदि आप स्पाइडर का उपयोग कर रहे हैं, तो लाइनें बस पिछले सभी समाधानों के साथ लगातार प्रिंट करती हैं। इससे बचने का एक तरीका है:

for i in range(1000):
    print('\r' + str(round(i/len(df)*100,1)) + '% complete', end='')
    sys.stdout.flush()

यह मेरे लिए एकमात्र कार्यशील समाधान था (पायथन 3.8, विंडोज, पाइकार्म)।
z33k

0

इसके उपयोग के लिए रेमी उत्तर के आधार पर Python 2.7+:

from __future__ import print_function
import time

# status generator
def range_with_status(total):
    """ iterate from 0 to total and show progress in console """
    import sys
    n = 0
    while n < total:
        done = '#' * (n + 1)
        todo = '-' * (total - n - 1)
        s = '<{0}>'.format(done + todo)
        if not todo:
            s += '\n'
        if n > 0:
            s = '\r' + s
        print(s, end='\r')
        sys.stdout.flush()
        yield n
        n += 1


# example for use of status generator
for i in range_with_status(50):
    time.sleep(0.2)

0

केवल Python 3.6+और listकेवल intएस के बजाय , साथ ही साथ अपनी कंसोल विंडो की पूरी चौड़ाई का उपयोग करने और एक नई लाइन को पार नहीं करने के लिए, आप निम्नलिखित का उपयोग कर सकते हैं:

नोट: कृपया सूचित किया जाए, कि फ़ंक्शन get_console_with()केवल लिनक्स आधारित सिस्टम पर काम करेगा, और जैसे कि आपको इसे विंडोज पर काम करने के लिए फिर से लिखना होगा।

import os
import time

def get_console_width():
    """Returns the width of console.

    NOTE: The below implementation works only on Linux-based operating systems.
    If you wish to use it on another OS, please make sure to modify it appropriately.
    """
    return int(os.popen('stty size', 'r').read().split()[1])


def range_with_progress(list_of_elements):
    """Iterate through list with a progress bar shown in console."""

    # Get the total number of elements of the given list.
    total = len(list_of_elements)
    # Get the width of currently used console. Subtract 2 from the value for the
    # edge characters "[" and "]"
    max_width = get_console_width() - 2
    # Start iterating over the list.
    for index, element in enumerate(list_of_elements):
        # Compute how many characters should be printed as "done". It is simply
        # a percentage of work done multiplied by the width of the console. That
        # is: if we're on element 50 out of 100, that means we're 50% done, or
        # 0.5, and we should mark half of the entire console as "done".
        done = int(index / total * max_width)
        # Whatever is left, should be printed as "unfinished"
        remaining = max_width - done
        # Print to the console.
        print(f'[{done * "#"}{remaining * "."}]', end='\r')
        # yield the element to work with it
        yield element
    # Finally, print the full line. If you wish, you can also print whitespace
    # so that the progress bar disappears once you are done. In that case do not
    # forget to add the "end" parameter to print function.
    print(f'[{max_width * "#"}]')


if __name__ == '__main__':
    list_of_elements = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
    for e in range_with_progress(list_of_elements):
        time.sleep(0.2)


0

यदि आप पायथन 3 का उपयोग कर रहे हैं तो यह आपके लिए है और यह वास्तव में काम करता है।

print(value , sep='',end ='', file = sys.stdout , flush = False)

0

पायथन 3+ के लिए

for i in range(5):
    print(str(i) + '\r', sep='', end ='', file = sys.stdout , flush = False)

0

बस एक उलटी गिनती दिखाने के लिए यह पता लगा कि यह एक प्रतिशत के लिए भी काम करेगा।

import time
#Number of seconds to wait
i=15
#Until seconds has reached zero
while i > -1:
    #Ensure string overwrites the previous line by adding spaces at end
    print("\r{} seconds left.   ".format(i),end='')
        time.sleep(1)
        i-=1
    print("") #Adds newline after it's done

जब तक r / r ’के बाद जो भी आता है, वह पिछले तार की तुलना में एक ही लंबाई या अधिक (रिक्त स्थान सहित) होता है, तो यह उसी रेखा पर इसे अधिलेखित कर देगा। बस यह सुनिश्चित करें कि आप अंत = '' को शामिल करते हैं अन्यथा यह एक नई पंक्ति में प्रिंट हो जाएगा। उम्मीद है की वो मदद करदे!


0

ऑब्जेक्ट के लिए "पेगा" जो StartRunning (), StopRunning (), बूलियन getIsRunning () और पूर्णांक getProgress100 () 0 से 100 की रेंज में वैल्यू रिटर्न प्रदान करता है, यह रनिंग के दौरान टेक्स्ट प्रोग्रेस बार प्रदान करता है ...

now = time.time()
timeout = now + 30.0
last_progress = -1

pega.StartRunning()

while now < timeout and pega.getIsRunning():
    time.sleep(0.5)
    now = time.time()

    progress = pega.getTubProgress100()
    if progress != last_progress:
        print('\r'+'='*progress+'-'*(100-progress)+' ' + str(progress) + "% ", end='', flush=True)
        last_progress = progress

pega.StopRunning()

progress = pega.getTubProgress100()
print('\r'+'='*progress+'-'*(100-progress)+' ' + str(progress) + "% ", flush=True)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.