কোনও পুনরুক্তি পরিবর্তনশীল ছাড়া রেঞ্জ লুপের জন্য পাইথনটি প্রয়োগ করা সম্ভব?


186

এটি ছাড়া কি অনুসরণ করা সম্ভব i?

for i in range(some_number):
    # do something

যদি আপনি কিছু পরিমাণ এন বার করতে চান এবং বারবারের প্রয়োজন হয় না।


21
এটা একটা ভালো প্রশ্ন! পাইডেভ এমনকি 'অব্যবহৃত ভেরিয়েবল'-এর সতর্কবার্তা হিসাবে' i 'কে পতাকাঙ্কিত করে। নীচের সমাধানটি এই সতর্কতাটি সরিয়ে দেয়।
আশ্বিন নানজাপ্পা

@ আশ্বিন আপনি এই সতর্কতাটি সরাতে \ @UnusedVariable ব্যবহার করতে পারেন। দ্রষ্টব্য যে এই মন্তব্যটি চালিয়ে যাওয়ার জন্য আমার 'এট' চিহ্নটি থেকে বাঁচতে হবে।
রাফি খ্যাচাডৌড়িয়ান

আমি একই প্রশ্ন আপনি মাথা। এটি পাইলট সতর্কতা দিয়ে বিরক্তিকর। অবশ্যই আপনি @ রাফি খাট্টাডোরিয়ান প্রস্তাবিত অতিরিক্ত দমন দ্বারা সতর্কতাগুলি অক্ষম করতে পারেন। পাইলট সতর্কতা এবং দমন মন্তব্যগুলি এড়ানো ভাল হবে ।
ট্যাঙ্গোয়াল

উত্তর:


109

আমার মাথার উপরের অংশ, না।

আমি মনে করি আপনি সবচেয়ে ভাল করতে পারেন এটি হ'ল:

def loop(f,n):
    for i in xrange(n): f()

loop(lambda: <insert expression here>, 5)

তবে আমি মনে করি আপনি কেবল অতিরিক্ত দিয়ে বাঁচতে পারবেন i ভেরিয়েবলের ।

এখানে _ভেরিয়েবলটি ব্যবহার করার বিকল্পটি রয়েছে , যা বাস্তবে কেবল অন্য পরিবর্তনশীল।

for _ in range(n):
    do_something()

দ্রষ্টব্য যে _ইন্টারেক্টিভ পাইথন সেশনে ফিরে আসা শেষ ফলাফলটি অর্পণ করা হয়েছে:

>>> 1+2
3
>>> _
3

এই কারণে, আমি এই পদ্ধতিতে এটি ব্যবহার করব না। রায়ান উল্লিখিত কোন মূর্খতা সম্পর্কে আমি অসচেতন। এটি আপনার দোভাষীকে গোলমাল করতে পারে।

>>> for _ in xrange(10): pass
...
>>> _
9
>>> 1+2
3
>>> _
9

পাইথন ব্যাকরণ অনুসারে , এটি একটি গ্রহণযোগ্য পরিবর্তনশীল নাম:

identifier ::= (letter|"_") (letter | digit | "_")*

4
"তবে আমি মনে করি আপনি কেবল অতিরিক্ত" i "দিয়ে বাঁচতে পারবেন" হ্যাঁ এটি কেবল একাডেমিক পয়েন্ট।
জেমস ম্যাকমাহন

1
@ নেমো, আপনি _ রেঞ্জের জন্য চেষ্টা করতে পারেন (এন): আপনি যদি আলফানিউমেরিক নাম ব্যবহার করতে না চান তবে।
অজানা

_ কি এই ক্ষেত্রে একটি পরিবর্তনশীল? নাকি পাইথনের অন্য কিছু?
জেমস ম্যাকমাহন

1
@ নেমো হ্যাঁ এটি কেবল একটি গ্রহণযোগ্য পরিবর্তনশীল নাম। দোভাষীর মধ্যে, এটি স্বয়ংক্রিয়ভাবে আপনার করা শেষ প্রকাশটি নির্ধারিত হয়।
অজানা

3
@ কুরকজাক একটি পয়েন্ট আছে। ব্যবহার _এটি পরিষ্কার করে দেয় যে এটি উপেক্ষা করা উচিত। এটি করার কোনও অর্থ নেই তা বলা আপনার কোড সম্পর্কে মন্তব্য করার কোনও অর্থ নেই - কারণ এটি যাইহোক ঠিক একই রকম হবে।
লাম্বদা পরী

69

আপনি খুঁজছেন হতে পারে

for _ in itertools.repeat(None, times): ...

এটি timesপাইথনের বার বার পুনরাবৃত্তি করার দ্রুততম উপায় ।


2
আমি পারফরম্যান্স নিয়ে উদ্বিগ্ন ছিলাম না, বিবৃতিটি লেখার কোনও ক্ষুধার উপায় থাকলে আমি কেবল আগ্রহী ছিলাম was আমি প্রায় 2 বছর ধরে পাইথনটি বিক্ষিপ্তভাবে ব্যবহার করার সময় এখনও অনুভব করছি যে আমি খুব মিস করছি। Itertools এই জিনিসগুলির মধ্যে একটি, তথ্যের জন্য আপনাকে ধন্যবাদ।
জেমস ম্যাকমাহন

5
এটি আকর্ষণীয়, আমি এটি সম্পর্কে অবগত ছিলাম না। আমি কেবল ইটারটোল ডক্সে একবার দেখেছি; তবে আমি ভাবছি কেন কেবল রেঞ্জ বা এক্সরেঞ্জ ব্যবহারের চেয়ে দ্রুত?
si28719e

5
@ ব্ল্যাককেটল: এটি দ্রুত কারণ এটি এখনকার পুনরাবৃত্তি সূচকটি ফিরিয়ে আনার দরকার নেই যা এক্সরেঞ্জের ব্যয়ের একটি পরিমাপযোগ্য অংশ (এবং পাইথন 3 এর পরিসর, যা একটি পুনরুক্তি দেয়, একটি তালিকা নয়)। @ নেমো, রেঞ্জটি যতটা পারে ঠিক ততটাই অপ্টিমাইজড, তবে একটি লিস্ট তৈরি এবং ফিরানো দরকার একটি পুনরাবৃত্তির চেয়ে ভারী কাজ (পাই 3 এ রেঞ্জ, পি 2 এর এক্সরেঞ্জের মতো একটি পুনরাবৃত্তিকে ফিরিয়ে দেয়; পিছনের দিকের সামঞ্জস্যতা এ জাতীয় পরিবর্তনের অনুমতি দেয় না) পি 2 তে), বিশেষত এমন একটি যা পৃথক মানের ফেরতের দরকার নেই।
অ্যালেক্স মার্তেলেলি 14

4
@ ক্রিশ্চিয়ান, হ্যাঁ, প্রতিবার একটি পাইথন ইন স্পষ্টভাবে প্রস্তুত এবং ফিরে আসছে, ইনক। জিসি কাজ, একটি পরিমাপযোগ্য ব্যয় আছে - অভ্যন্তরীণভাবে একটি কাউন্টার ব্যবহার করা কোনও বিষয় নয়।
অ্যালেক্স মার্টেলি

4
আমি এখন বুঝতে পেরেছি. পার্থক্যটি জিসি ওভারহেড থেকে আসে, "অ্যালগরিদম" থেকে নয়। যাইহোক, আমি একটি দ্রুত টাইমিট বেঞ্চমার্ক চালাচ্ছি এবং স্পিডআপটি ছিল 42 1.42x।
ক্রিশ্চিয়ান সিউপিতু

59

ব্যবহৃত হয় না এমন কোনও মান নির্ধারণের জন্য সাধারণ পরিচয়টি হ'ল এটির নামকরণ _

for _ in range(times):
    do_stuff()

18

সবাই আপনাকে _ যে ব্যবহারের পরামর্শ দিচ্ছে তা বলছে না যে _ প্রায়শই একটি গেটেক্সট ফাংশনের শর্টকাট হিসাবে ব্যবহৃত হয় , তাই আপনি যদি নিজের সফ্টওয়্যারটি একাধিক ভাষায় উপলভ্য হন তবে আপনি এটি ব্যবহার করা এড়ানো ভাল best অন্যান্য উদ্দেশ্যে।

import gettext
gettext.bindtextdomain('myapplication', '/path/to/my/language/directory')
gettext.textdomain('myapplication')
_ = gettext.gettext
# ...
print _('This is a translatable string.')

আমার কাছে এই ব্যবহারটি _একটি ভয়ানক ধারণা বলে মনে হচ্ছে, আমি এটির সাথে দ্বন্দ্ব বোধ করব না।
কিথডব্লিউএম

9

এখানে একটি এলোমেলো ধারণা দেওয়া হয়েছে যা ডেটা মডেল ( পাই 3 লিঙ্ক ) ব্যবহার করে (অপব্যবহার?)

class Counter(object):
    def __init__(self, val):
        self.val = val

    def __nonzero__(self):
        self.val -= 1
        return self.val >= 0
    __bool__ = __nonzero__  # Alias to Py3 name to make code work unchanged on Py2 and Py3

x = Counter(5)
while x:
    # Do something
    pass

আমি ভাবছি স্ট্যান্ডার্ড লাইব্রেরিতে এরকম কিছু আছে কিনা?


10
আমি মনে করি __nonzero__পার্শ্ব-প্রতিক্রিয়াযুক্ত যেমন একটি পদ্ধতি থাকা একটি ভয়ঙ্কর ধারণা।
চোরমাস্টার

2
আমি __call__পরিবর্তে ব্যবহার করতে হবে। while x():লিখতে তেমন শক্ত নয়।
জেসমিজন

1
নাম এড়ানোর পক্ষে যুক্তিও রয়েছে Counter; নিশ্চিত, এটি সংরক্ষিত নয় বা অন্তর্নির্মিত স্কোপে নেই, তবে collections.Counterএটি একটি জিনিস এবং একই নামের একটি শ্রেণি তৈরি করা রক্ষণাবেক্ষণকারীদের বিভ্রান্তির ঝুঁকি নিয়েছে (এমনটি নয় যে এটি ইতিমধ্যে ঝুঁকিপূর্ণ নয়)।
শ্যাডোর্যাঞ্জার

7

গেটেক্সটেক্স সহ নাম-কলিশন রোধ করতে আপনি _11 (বা কোনও নম্বর বা অন্য কোনও অবৈধ শনাক্তকারী) ব্যবহার করতে পারেন। যে কোনও সময় আপনি আন্ডারস্কোর + অবৈধ শনাক্তকারী ব্যবহার করেন আপনি একটি ডামি নাম পান যা লুপের জন্য ব্যবহার করা যেতে পারে।


নিস! পাইডিভ আপনার সাথে একমত: এটি "অব্যবহৃত পরিবর্তনশীল" হলুদ সতর্কতা থেকে মুক্তি পেয়ে যায়।
মাইক রডেন্ট

2

উত্তরটি পুনরুক্তি ব্যবহার করে আপনার কোন সমস্যার উপরে নির্ভর করবে? ব্যবহার হতে পারে

i = 100
while i:
    print i
    i-=1

অথবা

def loop(N, doSomething):
    if not N:
        return
    print doSomething(N)
    loop(N-1, doSomething)

loop(100, lambda a:a)

তবে প্রকৃতপক্ষে আমি এই জাতীয় পন্থাগুলি ব্যবহার করার কোনও অর্থ দেখতে পাচ্ছি না


1
দ্রষ্টব্য: পাইথন (অবশ্যই সিপিথন রেফারেন্স ইন্টারপ্রেটার কমপক্ষে, সম্ভবত অন্যদের মধ্যে বেশিরভাগই নয়) লেজ পুনরাবৃত্তিটি অনুকূল করে না, সুতরাং এন এর মানের আশেপাশের কিছুতে সীমাবদ্ধ থাকবে sys.getrecursionlimit()(যা নিম্ন চারে কোথাও ডিফল্ট হবে) সিপিথনে অঙ্কের পরিসীমা); ব্যবহার sys.setrecursionlimitসীমা বাড়াতে হবে, কিন্তু শেষ পর্যন্ত আপনি সি স্ট্যাক সীমা আঘাত চাই এবং অনুবাদক একটি স্ট্যাক ওভারফ্লো সঙ্গে মারা হবে (শুধুমাত্র একটা চমৎকার উত্থাপন RuntimeError/ RecursionError)।
শ্যাডোর্যাঞ্জার


1

বিনা বিহীন কাউন্টারটির পরিবর্তে এখন আপনার কাছে বিনা শোধিত তালিকা রয়েছে। সেরা সমাধান হ'ল "_" দিয়ে শুরু হওয়া একটি ভেরিয়েবল ব্যবহার করা, যা সিনট্যাক্স চেকারকে বলে যে আপনি ভেরিয়েবলটি ব্যবহার করছেন না তা আপনি সচেতন are

x = range(5)
while x:
  x.pop()
  print "Work!"

0

আমি সাধারণত উপরে বর্ণিত সমাধানগুলির সাথে একমত হই। যথা:

  1. আন্ডারস্কোর ইন- forলুপ ব্যবহার (2 এবং আরও লাইন)
  2. একটি সাধারণ whileকাউন্টার সংজ্ঞা দেওয়া (3 এবং আরও লাইন)
  3. __nonzero__বাস্তবায়নের সাথে একটি কাস্টম শ্রেণীর ঘোষণা (আরও অনেক লাইন)

# 3 এর মতো যদি কোনও অবজেক্টের সংজ্ঞা দেওয়া হয় তবে আমি কীওয়ার্ড সহ প্রোটোকল প্রয়োগ বা কনস্টেক্সলিব প্রয়োগ করার পরামর্শ দেব

আরও আমি আরও একটি সমাধান প্রস্তাব। এটি একটি 3 লাইনার এবং এটি সর্বোচ্চ কমনীয়তার নয়, তবে এটি ইটারটোলস প্যাকেজটি ব্যবহার করে এবং এটি আগ্রহী হতে পারে।

from itertools import (chain, repeat)

times = chain(repeat(True, 2), repeat(False))
while next(times):
    print 'do stuff!'

এই উদাহরণে 2 হল লুপটি পুনরাবৃত্তি করার সংখ্যা times চেইন দুটি পুনরাবৃত্তি পুনরাবৃত্তি মোড়ানো হয় , প্রথম সীমাবদ্ধ কিন্তু দ্বিতীয় অসীম। মনে রাখবেন যে এগুলি সত্য পুনরাবৃত্তকারী বস্তু, তাই তাদের অসীম মেমরির প্রয়োজন হয় না। স্পষ্টতই এটি অনেক ধীর তারপর সমাধান # 1 । কোনও ফাংশনের অংশ হিসাবে লিখিত না হলে এটি সময়ের পরিবর্তনের জন্য পরিষ্কার হতে পারে ।


2
chainঅপ্রয়োজনীয়, times = repeat(True, 2); while next(times, False):একই জিনিস।
আছাম্পিয়ন

0

আমরা নীচের সাথে কিছু মজা করেছি, তাই ভাগ করে নেওয়া আকর্ষণীয়:

class RepeatFunction:
    def __init__(self,n=1): self.n = n
    def __call__(self,Func):
        for i in xrange(self.n):
            Func()
        return Func


#----usage
k = 0

@RepeatFunction(7)                       #decorator for repeating function
def Job():
    global k
    print k
    k += 1

print '---------'
Job()

ফলাফল:

0
1
2
3
4
5
6
---------
7

0

যদি do_somethingএকটি সাধারণ ফাংশন হয় বা একটিতে আবৃত করা যায়, একটি সাধারণ সময় বার map()করতে পারে do_something range(some_number):

# Py2 version - map is eager, so it can be used alone
map(do_something, xrange(some_number))

# Py3 version - map is lazy, so it must be consumed to do the work at all;
# wrapping in list() would be equivalent to Py2, but if you don't use the return
# value, it's wastefully creating a temporary, possibly huge, list of junk.
# collections.deque with maxlen 0 can efficiently run a generator to exhaustion without
# storing any of the results; the itertools consume recipe uses it for that purpose.
from collections import deque

deque(map(do_something, range(some_number)), 0)

আপনি যদি যুক্তিগুলি পাস করতে চান তবে আপনি এটির টারলসের রেসিপিটিওdo_something পেতে পারেনrepeatfunc ভাল লেখা আছে:

একই যুক্তি পাস করতে:

from collections import deque
from itertools import repeat, starmap

args = (..., my args here, ...)

# Same as Py3 map above, you must consume starmap (it's a lazy generator, even on Py2)
deque(starmap(do_something, repeat(args, some_number)), 0)

বিভিন্ন যুক্তি পাস করতে:

argses = [(1, 2), (3, 4), ...]

deque(starmap(do_something, argses), 0)

-1

যদি আপনি সত্যিকার অর্থে কোনও নাম স্থাপন করা এড়াতে চান (হয় ওপি হিসাবে যেমন একটি পুনরাবৃত্তি পরিবর্তনশীল, বা অযাচিত তালিকা বা অযাচিত জেনারেটর যথাসময়ে সত্য হিসাবে প্রত্যাবর্তন করছেন) আপনি যদি সত্যিই চান তবে আপনি এটি করতে পারেন:

for type('', (), {}).x in range(somenumber):
    dosomething()

যে কৌশলটি ব্যবহার করা হয়েছে তা হ'ল একটি বেনাম শ্রেণি তৈরি করা type('', (), {})যার ফলশ্রুতিতে খালি নাম রয়েছে, তবে এনবি স্থানীয় বা বিশ্বব্যাপী নেমস্পেসে সন্নিবেশ করা হয়নি (এমনকি কোনও নামহীন নাম সরবরাহ করা হয়নি)। তারপরে আপনি সেই শ্রেণীর একজন সদস্যকে পুনরাবৃত্তকরণ ভেরিয়েবল হিসাবে ব্যবহার করেন যা অ্যাক্সেসযোগ্য কারণ যে শ্রেণীর এটির সদস্য সেটি অ্যাক্সেসযোগ্য।


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

মূলত, একটি নামযুক্ত ভেরিয়েবল এড়াতে (সাধারণত) প্রতিটি লুপের উপর নির্বিচারে পরিষ্কার করা হবে (যখন এটি পুনঃসেট হবে, এবং পুরানো মানটি পরিষ্কার হয়ে যাবে), আপনি একটি বিশাল নামবিহীন ভেরিয়েবল তৈরি করছেন যা অ-নিরঙ্কুশভাবে পরিষ্কার করা হয়, এবং সহজেই পারত অনেক দিন পর্যন্ত.
শ্যাডোর্যাঞ্জার


-7

কি সম্পর্কে:

while range(some_number):
    #do something

3
শর্তটি range(some_number)সর্বদা সত্য বলে এটি একটি অসীম লুপ !
মারাত্মক

@ বিস্ময়করভাবে: ঠিক আছে, এর some_numberচেয়ে কম বা সমান হলে 0এটি অসীম নয়, এটি কখনও চালায় না। :-) আর বরং একটি অসীম লুপ (বিশেষ করে Py2 দিকে) জন্য অদক্ষ এর, যেহেতু এটি একটি তাজা সৃষ্টি list(Py2) অথবা rangeপ্রতিটি পরীক্ষার জন্য বস্তু (Py3) (এটা দেখুন অনুবাদক এর বিন্দু থেকে একটি ধ্রুবক নয়, এটি লোড হয়েছে rangeএবং some_numberপ্রতিটি লুপ, কল করুন range, তারপরে ফলাফলটি পরীক্ষা করুন)।
শ্যাডোর্যাঞ্জার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.