অজগর উপায় একটি সূচক পরিবর্তনশীল ছাড়া এন বার কিছু করতে?


161

প্রতিদিন আমি অজগরকে বেশি বেশি ভালবাসি।

আজ, আমি কিছু কোড লিখছিলাম যেমন:

for i in xrange(N):
    do_something()

আমাকে এন বার কিছু করতে হয়েছিল। তবে প্রতিটি সময় i(সূচক ভেরিয়েবল) এর মানের উপর নির্ভর করে না । আমি বুঝতে পেরেছিলাম যে আমি এমন একটি পরিবর্তনশীল তৈরি করছি যা আমি কখনই ব্যবহার করি নি ( i) এবং আমি ভেবেছিলাম "অবশ্যই এই অপ্রয়োজনীয় সূচক ভেরিয়েবলের প্রয়োজন ছাড়াই এটি করার আরও একটি পাইথোনিক উপায় রয়েছে।"

সুতরাং ... প্রশ্নটি হল: আপনি কী জানেন যে কীভাবে আরও সহজ (অজগর) সুন্দর উপায়ে এই সাধারণ কাজটি করা যায়?


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


5
দ্রষ্টব্য: পাইঞ্জন 3 এ এক্সরঞ্জের অস্তিত্ব নেই। rangeপরিবর্তে ব্যবহার করুন।
জন হেন্কেল

উত্তর:


110

লুপিংয়ের চেয়ে কিছুটা দ্রুত পন্থা xrange(N)হ'ল:

import itertools

for _ in itertools.repeat(None, N):
    do_something()

3
কত দ্রুত? পাইথন ৩.১-এ এখনও কি পার্থক্য রয়েছে?
হামিশ গ্রুবিজন

15
@ হামিশ: ২.6 সহ আমার পরীক্ষাটি 32% দ্রুত বলে (23.2 আমাদের বনাম 17.6 এন = 1000 এর জন্য)। তবে সে যাইহোক সত্যিই সময়। আমি ওপির কোডটি ডিফল্ট করব কারণ এটি তাত্ক্ষণিকভাবে পাঠযোগ্য (আমার কাছে)।
মাইক বোয়ার্স

3
গতি সম্পর্কে জেনে রাখা ভাল। আমি অবশ্যই মাইকের ওপির কোডটি আরও পঠনযোগ্য হওয়ার সংবেদনটি প্রতিধ্বনিত করছি।
ওয়েন ওয়ার্নার

@ ওয়েইন, আমার ধারণা অভ্যাসটি সত্যিই খুব শক্তিশালী - আপনি এটির অভ্যস্ত হওয়া বাদে অন্য কেন "0 থেকে এন -1 পর্যন্ত গণনা করা হবে [[এবং পুরোপুরি গণনা উপেক্ষা করবেন]] প্রতিবার এই গণনা সম্পাদন করছেন? নির্ভরশীল অপারেশন "নিম্নলিখিত ক্রিয়াকলাপ পুনরাবৃত্তি এন" চেয়ে অভ্যন্তরীণভাবে আরও পরিষ্কার হতে পারে ...?
অ্যালেক্স মার্টেলি

4
আপনি কি গতিটি সত্যিই প্রাসঙ্গিক? এটি কি তাই নয় যে আপনি যদি সেই লুপটিতে উল্লেখযোগ্য কিছু করেন তবে আপনার সম্ভবত পুনরাবৃত্ত শৈলীর পছন্দ হিসাবে শত বা হাজার হাজার সময় লাগবে?
হেনিং

55

_ ভেরিয়েবলটি ব্যবহার করুন, যেমন আমি এই প্রশ্নটি জিজ্ঞাসা করার সময় শিখেছি , উদাহরণস্বরূপ:

# A long way to do integer exponentiation
num = 2
power = 3
product = 1
for _ in xrange(power):
    product *= num
print product

6
ডাউনভোটার নয় তবে এটি হতে পারে কারণ আপনি উত্তরে আরও বিশদ যুক্ত করার পরিবর্তে অন্য পোস্টে উল্লেখ করছেন
ডাউনওয়েট

5
@ ডাউনগোট: প্রতিক্রিয়ার জন্য ধন্যবাদ এই বলেছিল, এই প্রতিমাটি সম্পর্কে খুব বেশি কিছু বলার নেই। অন্য একটি পোস্টে উল্লেখ করার ক্ষেত্রে আমার বক্তব্যটি উল্লেখ করা ছিল যে কোনও অনুসন্ধানের উত্তর সম্ভবত তৈরি করেছে। আমি বিড়ম্বনাজনক যে এই প্রশ্নটি অন্য এক হিসাবে বিভিন্ন বার upvotes আছে।
গ্রিনম্যাট

39

আমি কেবল ব্যবহার করি for _ in range(n), এটি সোজা কথা। এটি পাইথন 2 তে বিশাল সংখ্যার পুরো তালিকাটি তৈরি করতে চলেছে, তবে আপনি পাইথন 3 ব্যবহার করলে এটি কোনও সমস্যা নয়।


10

যেহেতু ফাংশনটি প্রথম শ্রেণির নাগরিক, আপনি ছোট মোড়ক লিখতে পারেন (অ্যালেক্সের উত্তর থেকে)

def repeat(f, N):
    for _ in itertools.repeat(None, N): f()

তাহলে আপনি যুক্তি হিসাবে ফাংশনটি পাস করতে পারেন can


@ হামিশ: প্রায় কিছুই না। (অ্যালেক্সের উত্তরের সময়কালের মতো 0.2 শর্তের ব্যবধানের জন্য একই অবস্থায় আমাদের প্রতি লুপ প্রতি 17.8))
মাইক বোয়ার্স

9

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


8

আমি বিভিন্ন উত্তরগুলি সত্যিই মার্জিত দেখতে পেয়েছি (বিশেষত অ্যালেক্স মার্তেলির) তবে আমি প্রথম হাতের পারফরম্যান্সকে প্রশংসিত করতে চেয়েছিলাম, তাই আমি নিম্নলিখিত স্ক্রিপ্টটি রান্না করেছি:

from itertools import repeat
N = 10000000

def payload(a):
    pass

def standard(N):
    for x in range(N):
        payload(None)

def underscore(N):
    for _ in range(N):
        payload(None)

def loopiter(N):
    for _ in repeat(None, N):
        payload(None)

def loopiter2(N):
    for _ in map(payload, repeat(None, N)):
        pass

if __name__ == '__main__':
    import timeit
    print("standard: ",timeit.timeit("standard({})".format(N),
        setup="from __main__ import standard", number=1))
    print("underscore: ",timeit.timeit("underscore({})".format(N),
        setup="from __main__ import underscore", number=1))
    print("loopiter: ",timeit.timeit("loopiter({})".format(N),
        setup="from __main__ import loopiter", number=1))
    print("loopiter2: ",timeit.timeit("loopiter2({})".format(N),
        setup="from __main__ import loopiter2", number=1))

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

standard:  0.8398549720004667
underscore:  0.8413165839992871
loopiter:  0.7110594899968419
loopiter2:  0.5891903560004721

সুতরাং মানচিত্রটি ব্যবহার করে লুপের জন্য মানের তুলনায় প্রায় 30% এবং মার্তেলির চেয়ে 19% অতিরিক্ত উন্নতি পাওয়া যায়।


4

ধরে নিন যে আপনি do_someting কে একটি ক্রিয়া হিসাবে সংজ্ঞায়িত করেছেন এবং আপনি এটি এন বার সম্পাদন করতে চান । আপনি নিম্নলিখিত চেষ্টা করতে পারেন:

todos = [do_something] * N  
for doit in todos:  
    doit()

45
অবশ্যই। আসুন শুধু ফাংশনটিকে এক মিলিয়ন বার কল করি না, আসুন এক মিলিয়ন আইটেমের তালিকাও বরাদ্দ দিন। সিপিইউ যদি কাজ করে, তবে স্মৃতিশক্তিটিও কি একটু চাপ দেওয়া উচিত নয়? উত্তরটি অবশ্যই "দরকারী নয়" হিসাবে চিহ্নিত করা যায় না (এটি একটি ভিন্ন, কার্যকরী পদ্ধতির দেখায়) তাই আমি হ্রাস করতে পারি না, তবে আমি একমত নই এবং আমি এর সম্পূর্ণ বিরোধী।
tzot

1
এটি কি একই ফাংশন মানটির জন্য এন রেফারেন্সের একটি তালিকা নয়?
নিক ম্যাককুরডি

বরং fn() for fn in itertools.repeat(do_something, N)অ্যারে প্রাক উত্পন্ন উত্পাদন এবং সংরক্ষণ করা ভাল ... এটি আমার পছন্দসই প্রতিমা।
F1 গুজব

1
@tzot কেন সুরক্ষিত সুর? এই ব্যক্তি একটি উত্তর লেখার জন্য প্রচেষ্টা চালিয়েছে এবং এখন ভবিষ্যতে অবদান থেকে নিরুৎসাহিত হতে পারে। এমনকি যদি এটিতে পারফরম্যান্সের প্রভাব থাকে তবে এটি একটি কার্যকরী বিকল্প এবং বিশেষত যদি এন ছোট হয় তবে পারফরম্যান্স / মেমরির প্রভাবগুলি উল্লেখযোগ্য নয়।
ডেভিডসকলগান

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

1

লুপ লুপ সম্পর্কে কি?

while times > 0:
    do_something()
    times -= 1

আপনার ইতিমধ্যে পরিবর্তনশীল রয়েছে; কেন এটি ব্যবহার করবেন না?


1
আমার একমাত্র চিন্তাভাবনাটি হ'ল এটি একটি বনাম কোডের 3 টি লাইন (?)
এজেপি

2
@ এজেপি - আরও 4 লাইন বনাম 2 লাইনের মতো
আর্টঅফ ওয়ারফেয়ার

ওভারহেডগুলির সাথে তুলনা (বার> 0) এবং হ্রাস (বার - = 1) যুক্ত করে ... লুপের জন্য এতটা ধীর ...
F1Rumors 10'16

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