পার্শ্ব প্রতিক্রিয়াগুলির জন্য তালিকা বোঝার ব্যবহার করা কি পাইথোনিক?


108

এমন কোনও ফাংশন সম্পর্কে চিন্তা করুন যা আমি এর পার্শ্ব প্রতিক্রিয়াগুলির জন্য কল করছি, মানগুলি না ফেরানোর জন্য (যেমন স্ক্রিনে মুদ্রণ করা, জিইউআই আপডেট করা, কোনও ফাইলে মুদ্রণ করা ইত্যাদি)।

def fun_with_side_effects(x):
    ...side effects...
    return y

এখন, এই ফানকে কল করার জন্য তালিকার বোঝাপড়াটি ব্যবহার করা কি পাইথোনিক :

[fun_with_side_effects(x) for x in y if (...conditions...)]

মনে রাখবেন যে আমি কোথাও তালিকাটি সংরক্ষণ করি না

বা আমি কি এই ফানকে এইভাবে ডাকি:

for x in y:
    if (...conditions...):
        fun_with_side_effects(x)

কোনটি ভাল এবং কেন?


6
এটি সীমান্তরেখা, তবে আপনি সম্ভবত সমর্থনের চেয়ে বেশি বিরোধিতা করবেন। আমি এটি থেকে বেরিয়ে যাচ্ছি: ^)
jcomeau_ictx

6
এটি একটি সহজ পছন্দ। পঠনযোগ্যতার গণনা - এটি দ্বিতীয় উপায়ে করুন। আপনি যদি আপনার স্ক্রিনে 2 টি অতিরিক্ত লাইন মাপসই করতে না পারেন তবে আরও বড় মনিটর পেতে পারেন :)
জন লা রুই

1
তালিকা অনুধাবন অযৌক্তিক যেহেতু এটি "স্পষ্টকৃতের চেয়ে সুস্পষ্ট ভাল" লঙ্ঘন করে - আপনি অন্য নির্মাণে একটি লুপ লুকিয়ে রাখছেন।
ফ্রেড ফু

3
@ এলারসম্যানস: কেবলমাত্র জিভিআর যদি বুঝতে পারতেন যে তিনি যখন প্রথম তালিকায় তালিকাটি বোঝার জন্য প্রবর্তন করেছিলেন!
স্টিভ জেসপ

2
@ এলারসম্যানস, স্টিভ জেসোপ, আমি মনে করি একটি লুপ হিসাবে একটি তালিকা বোধগম্যতা কল্পনা করা ভুল। এটি একটি লুপ হিসাবে ভাল প্রয়োগ করা যেতে পারে, তবে এর মতো নির্মানের বিন্দুটি একটি কার্যকরী এবং (ধারণামূলকভাবে) সমান্তরাল উপায়ে সামগ্রিক ডেটাতে পরিচালনা করা। সিনট্যাক্সে যদি সমস্যা হয়, তবে এটি for ... inউভয় ক্ষেত্রেই ব্যবহৃত হয় - যা এই জাতীয় প্রশ্নের দিকে নিয়ে যায়!
প্রেরক

উত্তর:


84

এটি করা খুব পাইথোনিক বিরোধী, এবং যে কোনও সিজনযুক্ত পাইথনিস্তা আপনাকে এটির জন্য নরক দেবে। মধ্যবর্তী তালিকাটি তৈরি হওয়ার পরে তা ফেলে দেওয়া হয় এবং এটি সম্ভবত খুব, খুব বড় এবং তাই তৈরির জন্য ব্যয়বহুল হতে পারে।


5
তাহলে এর চেয়ে বেশি অজগর উপায় কী হবে?
জোছিম সউর

6
যে তালিকাটি চারপাশে রাখে না; অর্থাত্ দ্বিতীয় উপায়ে কিছু বৈকল্পিক (এর থেকে মুক্তি পাওয়ার জন্য আমি forআগে জিনেক্স ব্যবহার করে পরিচিত ছিলাম if)।
Ignacio Vazquez-Abram

6
@ জোয়াচিম সৌর: উপরোক্ত উদাহরণ 2। একটি যথাযথ, স্পষ্ট, অ-তালিকা-বোধগম্য লুপ। স্পষ্ট। স্পষ্ট. সুস্পষ্ট।
এসলট

31

আপনার একটি তালিকা বোধগম্যতা ব্যবহার করা উচিত নয় , কারণ লোকেরা যেমন বলেছে যে আপনার প্রয়োজন নেই এমন একটি বৃহত অস্থায়ী তালিকা তৈরি করবে। নিম্নলিখিত দুটি পদ্ধতি সমতুল্য:

consume(side_effects(x) for x in xs)

for x in xs:
    side_effects(x)

ম্যান পৃষ্ঠা consumeথেকে সংজ্ঞা সহ itertools:

def consume(iterator, n=None):
    "Advance the iterator n-steps ahead. If n is none, consume entirely."
    # Use functions that consume iterators at C speed.
    if n is None:
        # feed the entire iterator into a zero-length deque
        collections.deque(iterator, maxlen=0)
    else:
        # advance to the empty slice starting at position n
        next(islice(iterator, n, n), None)

অবশ্যই, দ্বিতীয়টি আরও স্পষ্ট এবং বোঝা সহজ।


@ পল: আমি মনে করি এটি হওয়া উচিত। এবং প্রকৃতপক্ষে আপনি পারেন, যদিও mapকেউ স্বতঃস্ফূর্ত হতে পারে যদি কেউ এর আগে কার্যকরী প্রোগ্রামিং না করে থাকে।
ক্যাট্রিয়েল

4
নিশ্চিত না যে এটি বিশেষত মূর্তিমান। সুস্পষ্ট লুপটি ব্যবহার করার কোনও সুবিধা নেই।
মার্সিন

1
সমাধানটি হলconsume = collections.deque(maxlen=0).extend
PaulMcG

24

তালিকা বোধগম্য তালিকা তৈরির জন্য। এবং যদি না আপনি প্রকৃতপক্ষে একটি তালিকা তৈরি করেন তবে আপনার তালিকার বোধগম্যতা ব্যবহার করা উচিত নয়

সুতরাং আমি দ্বিতীয় বিকল্পটি পেয়েছিলাম, কেবল তালিকার উপরে পুনরাবৃত্তি করব এবং তারপরে শর্তগুলি প্রয়োগ করার পরে ফাংশনটি কল করুন।


6
আমি আরও এগিয়ে যাব এবং বলব যে একটি তালিকা বোঝার অভ্যন্তরের পার্শ্ব প্রতিক্রিয়াগুলি অস্বাভাবিক, অপ্রত্যাশিত এবং অতএব মন্দ, এমনকি আপনি যখন কাজটি সম্পন্ন করছেন তখন ফলাফলের তালিকাটি ব্যবহার করছেন।
মার্ক রান্সম

11

দ্বিতীয় ভাল।

সেই ব্যক্তির কথা চিন্তা করুন যাকে আপনার কোড বোঝার প্রয়োজন হবে। প্রথমটি দিয়ে আপনি সহজেই খারাপ কর্মফল পেতে পারেন :)

ফিল্টার () ব্যবহার করে আপনি দুজনের মাঝে যেতে পারেন। উদাহরণ বিবেচনা করুন:

y=[1,2,3,4,5,6]
def func(x):
    print "call with %r"%x

for x in filter(lambda x: x>3, y):
    func(x)

10
আপনার ল্যাম্বদা হিসাবে অনেক ভাল লেখা হয় lambda x : x > 3
PaulMcG

এমনকি আপনার ফিল্টারও লাগবে না। শুধু ডান বন্ধনী একটি জেনারেটর অভিব্যক্তি এখানে রাখুন: for el in (x for x in y if x > 3):elএবং xএকই নাম থাকতে পারে, তবে এটি লোককে বিভ্রান্ত করতে পারে।
সর্বনিম্ন

3

আপনার লক্ষ্য উপর নির্ভর করে।

আপনি যদি কোনও তালিকার প্রতিটি বস্তুর উপর কিছু অপারেশন করার চেষ্টা করছেন, তবে দ্বিতীয় পদ্ধতির গ্রহণ করা উচিত।

আপনি যদি অন্য একটি তালিকা থেকে একটি তালিকা উত্পন্ন করার চেষ্টা করছেন, আপনি তালিকা বোঝার ব্যবহার করতে পারেন।

সুস্পষ্ট বর্ণিত চেয়ে ভাল। সহজ জটিল চেয়ে ভাল। (পাইথন জেন)


0

আপনি করতে পারেন

for z in (fun_with_side_effects(x) for x in y if (...conditions...)): pass

তবে এটি খুব সুন্দর নয়।


-1

এর পার্শ্ব প্রতিক্রিয়াগুলির জন্য একটি তালিকা বোঝার ব্যবহার করা কুশ্রী, অ-পাইথোনিক, অদক্ষ এবং আমি এটি করব না it আমি forপরিবর্তে একটি লুপ ব্যবহার করব, কারণ একটি forলুপ একটি পদ্ধতিগত শৈলীর সংকেত দেয় যেখানে পার্শ্ব প্রতিক্রিয়াগুলি গুরুত্বপূর্ণ।

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

any(fun_with_side_effects(x) and False for x in y if (...conditions...))

বা:

all(fun_with_side_effects(x) or True for x in y if (...conditions...))

এগুলি জেনারেটর এক্সপ্রেশন এবং এগুলি এলোমেলো তালিকা তৈরি করে না যা ছিটকে যায়। আমি মনে করি allফর্মটি সম্ভবত কিছুটা আরও স্পষ্ট, যদিও আমি মনে করি উভয় বিভ্রান্তিকর এবং ব্যবহার করা উচিত নয়।

আমি মনে করি এটি কুরুচিপূর্ণ এবং আমি কোডে আসলে এটি করব না। তবে আপনি যদি এই ফ্যাশনে আপনার লুপগুলি বাস্তবায়নের জন্য জোর করেন তবে আমি এটিই করব।

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


fun_with_side_effectsসত্য যদি ফিরে আসে?
ক্যাট্রিয়েল

7
আমি মনে করি এই নিরাময়টি রোগের চেয়েও খারাপ - itertools.consume অনেক বেশি পরিষ্কার।
PaulMcG

@ পলমিসজি - এর itertools.consumeঅস্তিত্ব নেই, কারণ পার্শ্ব-প্রতিক্রিয়া সহ বোঝাগুলি ব্যবহার করা খারাপ।
সর্বজনীন

1
দেখা যাচ্ছে যে আমি ভুল হয়ে গিয়েছিলাম এবং স্টাডিলেব হিসাবে এটি কখনও উপস্থিত ছিল না । এটা তোলে হয় : itertools দস্তাবেজে একটি রেসিপি docs.python.org/3/library/...
PaulMcG
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.