বোধন বনাম মানচিত্র তালিকাভুক্ত করুন


732

map()ওভার তালিকা বোঝার বা তদ্বিপরীত ব্যবহার পছন্দ করার কোনও কারণ আছে কি ? এগুলির উভয়ই কি সাধারণভাবে বেশি দক্ষ বা অন্যের চেয়ে সাধারণভাবে বেশি পাইথোনিক হিসাবে বিবেচিত হয়?


8
নোট করুন যে পাইলিন্ট সতর্ক করে দিয়েছে আপনি যদি তালিকা বোধের পরিবর্তে মানচিত্র ব্যবহার করেন তবে ডাব্লু0141 বার্তাটি দেখুন
লম্ব্রিক

2
@ লুম্ব্রিক, আমি নিশ্চিত নই তবে ল্যাম্বদা মানচিত্রে ব্যবহার করা হলেই তা তা করে।
0xc0de

উত্তর:


660

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

ঠিক একই ফাংশনটি ব্যবহার করার সময় মানচিত্রের ক্ষুদ্র গতির সুবিধার একটি উদাহরণ:

$ python -mtimeit -s'xs=range(10)' 'map(hex, xs)'
100000 loops, best of 3: 4.86 usec per loop
$ python -mtimeit -s'xs=range(10)' '[hex(x) for x in xs]'
100000 loops, best of 3: 5.58 usec per loop

যখন মানচিত্রে ল্যাম্বডা দরকার হয় তখন পারফরম্যান্স তুলনা কীভাবে সম্পূর্ণ বিপরীত হয়:

$ python -mtimeit -s'xs=range(10)' 'map(lambda x: x+2, xs)'
100000 loops, best of 3: 4.24 usec per loop
$ python -mtimeit -s'xs=range(10)' '[x+2 for x in xs]'
100000 loops, best of 3: 2.32 usec per loop

39
হ্যাঁ, প্রকৃতপক্ষে আমাদের কাজকর্মের পাইথন স্টাইল গাইড ম্যাপ এবং ফিল্টারের বিরুদ্ধে লিস্টকম্পের স্পষ্টতই ক্ষতিপূরণ দেয় (এমনকি ক্ষুদ্র কিন্তু পরিমাপযোগ্য পারফরম্যান্স উন্নতির মানচিত্রের কিছু উল্লেখ করতে পারে না ;-)।
অ্যালেক্স মার্টেলি

46
অ্যালেক্সের অসীম স্টাইল পয়েন্টগুলিতে কিবাশ করা উচিত নয়, তবে কখনও কখনও মানচিত্রটি আমার কাছে পড়া সহজ মনে হয়: ডেটা = মানচিত্র (স্ট্রিম, কিছু_লিস্ট_অফ_বজেক্টস)। কিছু অন্যান্য বেশী ... operator.attrgetter, operator.itemgetter, ইত্যাদি
গ্রেগ লিন্ড

57
map(operator.attrgetter('foo'), objs)এর চেয়ে পড়া সহজ [o.foo for o in objs]?!
অ্যালেক্স মার্টেলি

52
@ অ্যালেক্স: আমি oএখানে যেমন অপ্রয়োজনীয় নাম প্রবর্তন না করা পছন্দ করি এবং কেন আপনার উদাহরণগুলি দেখায়।
রিড বার্টন

29
যদিও আমি মনে করি @ গ্রেগলিন্ডের str()উদাহরণ রয়েছে, যদিও তার উদাহরণ রয়েছে।
এরিক হে লেবিগোট

474

মামলা

  • সাধারণ ক্ষেত্রে : প্রায় সবসময়, আপনি পাইথনে একটি তালিকা বোঝার ব্যবহার করতে চাইবেন কারণ আপনি আপনার কোডটি পড়ছেন এমন নবাগত প্রোগ্রামারদের সাথে কী করছেন তা আরও স্পষ্ট। (এটি অন্যান্য ভাষাগুলির ক্ষেত্রে প্রযোজ্য নয়, যেখানে অন্যান্য প্রতিমা প্রয়োগ করতে পারে)) পাইথন প্রোগ্রামারদের আপনি কী করছেন তা আরও স্পষ্ট হবে, যেহেতু তালিকা অনুধাবনগুলি পুনরাবৃত্তির জন্য পাইথনের ডি-ফ্যাক্টো স্ট্যান্ডার্ড; তারা হয় প্রত্যাশিত
  • কম-সাধারণ ক্ষেত্রে : তবে আপনার যদি ইতিমধ্যে কোনও ফাংশন সংজ্ঞায়িত করা থাকে mapতবে এটি ব্যবহার করা প্রায়শই যুক্তিসঙ্গত , যদিও এটি 'অপার্থিব' হিসাবে বিবেচিত হয়। উদাহরণস্বরূপ, map(sum, myLists)তুলনায় আরও মার্জিত / নিবিড় [sum(x) for x in myLists]। ডামি ভেরিয়েবল (যেমন sum(x) for x...বা sum(_) for _...বা sum(readableName) for readableName...) তৈরি করতে না পারা আপনি কমনীয়তা অর্জন করেছেন যা কেবল পুনরাবৃত্তি করতে হবে। একই যুক্তি মডিউলটির জন্য filterএবং reduceকিছু হোল্ড করে itertools: আপনার যদি ইতিমধ্যে কোনও কার্যকারিতা সহজ হয় তবে আপনি এগিয়ে যেতে পারেন এবং কিছু কার্যকরী প্রোগ্রামিং করতে পারেন। এটি কিছু পরিস্থিতিতে পঠনযোগ্যতা অর্জন করে এবং অন্যদের মধ্যে এটি হারাতে পারে (যেমন নভিশ প্রোগ্রামার, একাধিক যুক্তি) ... তবে আপনার কোডের পঠনযোগ্যতা যাইহোক আপনার মন্তব্যের উপর নির্ভর করে।
  • প্রায়শই কখনই নয় : আপনি mapফাংশনাল প্রোগ্রামিং করার সময় ফাংশনটি খাঁটি বিমূর্ত ফাংশন হিসাবে ব্যবহার করতে চাইতে পারেন , যেখানে আপনি ম্যাপিং করছেন mapবা কারি করছেন map, বা অন্যথায় mapকোনও ফাংশন হিসাবে কথা বলে উপকার পাবেন । উদাহরণস্বরূপ হাস্কেলের মধ্যে, কোনও ফান্টর ইন্টারফেস fmapযেকোন ডেটা স্ট্রাকচারের উপরে ম্যাপিংকে জেনারেলাইজ করে। এটি অজগরটিতে খুব অস্বাভাবিক কারণ অজগর ব্যাকরণ আপনাকে পুনরাবৃত্তির বিষয়ে কথা বলতে জেনারেটর-স্টাইল ব্যবহার করতে বাধ্য করে; আপনি এটি সহজেই সাধারণ করতে পারবেন না can't (এটি কখনও কখনও ভাল এবং কখনও কখনও খারাপ হয়)) আপনি সম্ভবত বিরল অজগর উদাহরণ নিয়ে আসতে পারেন যেখানে map(f, *lists)করণীয় যুক্তিযুক্ত। নিকটতম উদাহরণটি আমি সামনে আসতে পারি sumEach = partial(map,sum), এটি একটি ওয়ান-লাইনার যা মোটামুটি সমান:

def sumEach(myLists):
    return [sum(_) for _ in myLists]
  • কেবলমাত্র একটি forলুপ ব্যবহার করুন : আপনি অবশ্যই একটি লুপ ব্যবহার করতে পারেন। ক্রিয়ামূলক-প্রোগ্রামিং দৃষ্টিকোণ থেকে মার্জিত না হলেও, কখনও কখনও অ-স্থানীয় ভেরিয়েবলগুলি অজগর হিসাবে প্রেরণামূলক প্রোগ্রামিং ভাষাগুলিতে কোড পরিষ্কার করে দেয়, কারণ মানুষ সেভাবে কোড পড়তে অভ্যস্ত। লুপগুলি এছাড়াও, সাধারণত, সবচেয়ে কার্যকর যখন আপনি কেবল কোনও জটিল ক্রিয়াকলাপ করছেন যা তালিকা-বোধগম্যতা এবং মানচিত্রের মতো তালিকা তৈরি করছে না তার জন্য অনুকূলিত করা হয়েছে (উদাহরণস্বরূপ সংক্ষেপণ, বা একটি গাছ তৈরি করা ইত্যাদি) - কমপক্ষে least মেমরির ক্ষেত্রে কার্যকর (সময়ের প্রয়োজনে অগত্যা নয়, যেখানে আমি দুর্লভ স্থিতিশীল ফ্যাক্টরটি আশা করতাম, কিছু বিরল রোগতাত্ত্বিক আবর্জনা-সংগ্রহ হিচকি বাদ দিয়ে)

"Pythonism"

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

আলস্য

দক্ষতার দিক থেকে, বেশিরভাগ কার্যকরী প্রোগ্রামিং কনস্ট্রাক্টের মতো, ম্যাপটি আলস্য হতে পারে এবং বাস্তবে অজগরটি অলস। তার মানে আপনি এটি করতে পারেন ( পাইথন 3 এ ) এবং আপনার কম্পিউটারের স্মৃতিশক্তি চলে না এবং আপনার সমস্ত সংরক্ষণ করা ডেটা হারাবে:

>>> map(str, range(10**100))
<map object at 0x2201d50>

একটি তালিকা বোঝার সাথে এটি করার চেষ্টা করুন:

>>> [str(n) for n in range(10**100)]
# DO NOT TRY THIS AT HOME OR YOU WILL BE SAD #

মনে রাখবেন যে তালিকা অনুধাবনগুলিও সহজাতভাবে অলস, তবে পাইথন সেগুলি অ-অলস হিসাবে প্রয়োগ করতে বেছে নিয়েছে । তবুও, পাইথন জেনারেটর এক্সপ্রেশন আকারে অলস তালিকা বোঝার জন্য সমর্থন করে:

>>> (str(n) for n in range(10**100))
<generator object <genexpr> at 0xacbdef>

আপনি মূলত [...]সিনট্যাক্সটিকে লিস্টের কনস্ট্রাক্টরের মতো জেনারেটর এক্সপ্রেশন হিসাবে পাস হিসাবে ভাবতে পারেন list(x for x in range(5))

সংক্ষিপ্ত সংক্ষিপ্ত উদাহরণ

from operator import neg
print({x:x**2 for x in map(neg,range(5))})

print({x:x**2 for x in [-y for y in range(5)]})

print({x:x**2 for x in (-y for y in range(5))})

তালিকা বোধগম্য অলস, তাই আরও মেমরির প্রয়োজন হতে পারে (যদি না আপনি জেনারেটর বোঝাপড়া ব্যবহার করেন)। বর্গাকার বন্ধনীগুলি [...]প্রায়শই জিনিসগুলিকে সুস্পষ্ট করে তোলে, বিশেষত যখন বন্ধনীগুলির জগাখিচুড়িতে। অন্যদিকে, কখনও কখনও আপনি টাইপ করার মতো ভার্বোজ হয়ে শেষ করেন [x for x in...। যতক্ষণ আপনি আপনার পুনরাবৃত্তকারী ভেরিয়েবলগুলি সংক্ষিপ্ত রাখবেন ততক্ষণ আপনি নিজের কোডটি ইন্ডেন্ট না করলে তালিকা বোধগম্যতা সাধারণত পরিষ্কার হয়। তবে আপনি সর্বদা আপনার কোডটি প্রবেশ করতে পারেন।

print(
    {x:x**2 for x in (-y for y in range(5))}
)

বা জিনিসগুলি ভেঙে দিন:

rangeNeg5 = (-y for y in range(5))
print(
    {x:x**2 for x in rangeNeg5}
)

পাইথন 3 এর জন্য দক্ষতার তুলনা

map এখন অলস:

% python3 -mtimeit -s 'xs=range(1000)' 'f=lambda x:x' 'z=map(f,xs)'
1000000 loops, best of 3: 0.336 usec per loop            ^^^^^^^^^

অতএব আপনি যদি আপনার সমস্ত ডেটা ব্যবহার না করে থাকেন, বা আপনাকে কী পরিমাণ ডেটা প্রয়োজন তা সময়ের আগে জানা mapনা গেলে পাইথন 3 (এবং পাইথন 2 বা পাইথন 3 তে জেনারেটর এক্সপ্রেশন) প্রয়োজনীয় মুহুর্ত পর্যন্ত তাদের মানগুলি গণনা করা এড়াতে পারে। সাধারণত এটি ব্যবহার থেকে কোনও ওভারহেড ছাড়িয়ে যায় map। ক্ষয়ক্ষতিটি হ'ল এটি বেশিরভাগ কার্যকরী ভাষার বিপরীতে অজগরটিতে খুব সীমাবদ্ধ: আপনি কেবলমাত্র এই উপকারটি পাবেন যদি আপনি আপনার ডেটা বাম থেকে ডান "ক্রমে" অ্যাক্সেস করেন তবে পাইথন জেনারেটর এক্সপ্রেশনটি কেবলমাত্র আদেশটির মূল্যায়ন করা যেতে পারে x[0], x[1], x[2], ...

তবে আসুন আমরা বলি যে আমাদের একটি প্রাক-তৈরি ফাংশন রয়েছে যা fআমরা চাই mapএবং আমরা mapসঙ্গে সঙ্গে মূল্যায়ন জোর করে অলসতা উপেক্ষা করি list(...)। আমরা কিছু খুব আকর্ষণীয় ফলাফল পেয়েছি:

% python3 -mtimeit -s 'xs=range(1000)' 'f=lambda x:x' 'z=list(map(f,xs))'                                                                                                                                                
10000 loops, best of 3: 165/124/135 usec per loop        ^^^^^^^^^^^^^^^
                    for list(<map object>)

% python3 -mtimeit -s 'xs=range(1000)' 'f=lambda x:x' 'z=[f(x) for x in xs]'                                                                                                                                      
10000 loops, best of 3: 181/118/123 usec per loop        ^^^^^^^^^^^^^^^^^^
                    for list(<generator>), probably optimized

% python3 -mtimeit -s 'xs=range(1000)' 'f=lambda x:x' 'z=list(f(x) for x in xs)'                                                                                                                                    
1000 loops, best of 3: 215/150/150 usec per loop         ^^^^^^^^^^^^^^^^^^^^^^
                    for list(<generator>)

ফলাফলগুলি এএএ / বিবিবি / সিসিসি আকারে রয়েছে যেখানে A একটি সার্কা -২০১০ এর সাথে একটি অজগর ৩.???, এবং বি এবং সি-এর একটি সার্কা -৩০ এএমডি ওয়ার্কস্টেশন দিয়ে অজগর ৩.২.১ সহ সঞ্চালিত হয়েছিল, অত্যন্ত ভিন্ন হার্ডওয়্যার সহ। ফলাফলটি মনে হয় যে মানচিত্র এবং তালিকার বোধগম্যতা পারফরম্যান্সের সাথে তুলনীয়, যা অন্যান্য এলোমেলো কারণগুলির দ্বারা সবচেয়ে দৃ strongly়ভাবে প্রভাবিত হয়। আমরা তালিকা comprehensions আশা যখন একমাত্র জিনিস আমরা বলতে পারেন, যে হবে, অদ্ভুত বলে মনে হয় [...]জেনারেটরের এক্সপ্রেশন বেশী ভালো পারফর্ম করতে (...), mapযে জেনারেটরের এক্সপ্রেশন (আবার অভিমানী যে সব মান মূল্যায়ন / ব্যবহার করা হয়) আরও দক্ষ নয়।

এই পরীক্ষাগুলি একটি খুব সাধারণ ফাংশন (পরিচয় ফাংশন) ধরে নেয় তা উপলব্ধি করা গুরুত্বপূর্ণ; তবে এটি ঠিক আছে কারণ যদি ফাংশনটি জটিল হয়, তবে প্রোগ্রামের অন্যান্য বিষয়গুলির তুলনায় কর্মক্ষমতা ওভারহেড উপেক্ষিত হবে। (অন্যান্য সাধারণ বিষয়গুলির সাথে পরীক্ষা করা এখনও আকর্ষণীয় হতে পারে f=lambda x:x+x)

আপনি যদি অজগর সমাবেশ পড়ার বিষয়ে দক্ষ হন তবে আপনি disমডিউলটি বাস্তবে পর্দার আড়ালে কী ঘটছে তা দেখতে ব্যবহার করতে পারেন :

>>> listComp = compile('[f(x) for x in xs]', 'listComp', 'eval')
>>> dis.dis(listComp)
  1           0 LOAD_CONST               0 (<code object <listcomp> at 0x2511a48, file "listComp", line 1>) 
              3 MAKE_FUNCTION            0 
              6 LOAD_NAME                0 (xs) 
              9 GET_ITER             
             10 CALL_FUNCTION            1 
             13 RETURN_VALUE         
>>> listComp.co_consts
(<code object <listcomp> at 0x2511a48, file "listComp", line 1>,)
>>> dis.dis(listComp.co_consts[0])
  1           0 BUILD_LIST               0 
              3 LOAD_FAST                0 (.0) 
        >>    6 FOR_ITER                18 (to 27) 
              9 STORE_FAST               1 (x) 
             12 LOAD_GLOBAL              0 (f) 
             15 LOAD_FAST                1 (x) 
             18 CALL_FUNCTION            1 
             21 LIST_APPEND              2 
             24 JUMP_ABSOLUTE            6 
        >>   27 RETURN_VALUE

 

>>> listComp2 = compile('list(f(x) for x in xs)', 'listComp2', 'eval')
>>> dis.dis(listComp2)
  1           0 LOAD_NAME                0 (list) 
              3 LOAD_CONST               0 (<code object <genexpr> at 0x255bc68, file "listComp2", line 1>) 
              6 MAKE_FUNCTION            0 
              9 LOAD_NAME                1 (xs) 
             12 GET_ITER             
             13 CALL_FUNCTION            1 
             16 CALL_FUNCTION            1 
             19 RETURN_VALUE         
>>> listComp2.co_consts
(<code object <genexpr> at 0x255bc68, file "listComp2", line 1>,)
>>> dis.dis(listComp2.co_consts[0])
  1           0 LOAD_FAST                0 (.0) 
        >>    3 FOR_ITER                17 (to 23) 
              6 STORE_FAST               1 (x) 
              9 LOAD_GLOBAL              0 (f) 
             12 LOAD_FAST                1 (x) 
             15 CALL_FUNCTION            1 
             18 YIELD_VALUE          
             19 POP_TOP              
             20 JUMP_ABSOLUTE            3 
        >>   23 LOAD_CONST               0 (None) 
             26 RETURN_VALUE

 

>>> evalledMap = compile('list(map(f,xs))', 'evalledMap', 'eval')
>>> dis.dis(evalledMap)
  1           0 LOAD_NAME                0 (list) 
              3 LOAD_NAME                1 (map) 
              6 LOAD_NAME                2 (f) 
              9 LOAD_NAME                3 (xs) 
             12 CALL_FUNCTION            2 
             15 CALL_FUNCTION            1 
             18 RETURN_VALUE 

মনে হচ্ছে [...]সিনট্যাক্স এর চেয়ে ব্যবহার করা ভাল list(...)। দুর্ভাগ্যক্রমে mapক্লাসটি বিযুক্ত করার জন্য কিছুটা অস্বচ্ছ, তবে আমরা আমাদের গতি পরীক্ষা দিয়ে উপযুক্ত করতে পারি।


5
"অত্যন্ত কার্যকর ইটারটুলস মডিউলটি [সম্ভবত] স্টাইলের দিক থেকে অযৌক্তিক হিসাবে বিবেচিত হয়"। হুম। আমি "পাইথোনিক" শব্দটি পছন্দ করি না, তাই কিছুটা অর্থে আমি এর অর্থ কী তা বিবেচনা করি না, তবে আমি যারা এটি ব্যবহার করি তাদের পক্ষে এটি ন্যায়বিচার বলে মনে হয় না, "পাইথোনিকনেস" বিল্টিনস অনুসারে mapএবং filterস্ট্যান্ডার্ড লাইব্রেরির itertoolsসাথে সহজাতভাবে খারাপ স্টাইল are জিভিআর আসলে না বলে যে তারা হয় ভয়াবহ ভুল বা কেবল পারফরম্যান্সের জন্য, কেবলমাত্র প্রাকৃতিক উপসংহার যদি "পাইথোনিকনেস" বলে তবে এটি এটিকে বোকা হিসাবে ভুলে যাওয়া ;-)
স্টিভ জেসপ

4
@ স্টিভ জেসোপ: আসলে, গাইডো ভাবছেন যে পড়া ছেড়ে দেওয়া map/ filterপাইথন 3-এর পক্ষে একটি দুর্দান্ত ধারণা এবং অন্য পাইথনিস্টরা কেবলমাত্র বিদ্রোহই এগুলি বিল্ট-ইন নেমস্পেসে রেখেছিল ( reduceস্থানান্তরিত হওয়ার সময় functools)। আমি ব্যক্তিগতভাবে একমত নই ( mapএবং filterপূর্বনির্ধারিত, বিশেষত অন্তর্নির্মিত, ফাংশনগুলির সাথে ভাল, যদি lambdaপ্রয়োজন হয় তবে সেগুলি কখনই ব্যবহার করি না), তবে জিভিআর মূলত বছরের পর বছর ধরে এগুলিকে পাইথোনিক নয়।
শ্যাডোর্যাঞ্জার

@ শ্যাডোএ্যাঞ্জার: সত্য, তবে জিভিআর কি কখনও অপসারণের পরিকল্পনা করেছিল itertools? এই উত্তরটি থেকে আমি যে অংশটি উদ্ধৃত করছি তা হ'ল প্রধান দাবি যা আমাকে বিভ্রান্ত করে। আমি জানি না তার আদর্শ বিশ্বের কিনা, mapএবং filterথেকে সরে আসবেন itertools(অথবা functools) অথবা সম্পূর্ণরূপে যান, কিন্তু যেটা ক্ষেত্রে দেখা যায়, একবার এক বলছেন যে itertoolsতার সম্পূর্ণতা unPythonic হয়, তাহলে আমি সত্যিই জানি না কি "Pythonic" হয় বোঝাতে চাইলেও আমি মনে করি না এটি "জিভিআর লোকেরা ব্যবহারের পরামর্শ দেয়" এর মতো কিছু হতে পারে।
স্টিভ জেসোপ

2
@ স্টিভ জেসাপ: আমি কেবল সম্বোধন করছিলাম map/ filter, না itertools। কার্যকরী প্রোগ্রামিং পুরোপুরি Pythonic আছে ( itertools, functoolsএবং operatorসব মনের মধ্যে কার্যকরী প্রোগ্রামিং রেখে বিশেষভাবে ডিজাইন করা হয়েছে, এবং আমি পাইথন সব সময় কার্মিক বাগধারার ব্যবহার করুন), এবং itertoolsএর বিশেষভাবে বৈশিষ্ট্য ব্যাথা নিজেকে বাস্তবায়ন করতে হবে প্রদান করে, এটা mapএবং filterজেনারেটরের এক্সপ্রেশন সঙ্গে হচ্ছে অপ্রয়োজনীয় যা গিডো তাদের ঘৃণা করেছিল। itertoolsসবসময় ঠিক আছে।
শ্যাডোএ্যাঞ্জার

1
কোনও উত্তর থাকলে আমি এই উত্তরটি পছন্দ করতে পারি। ভাল করে বুঝিয়েছি।
নেলসনগন

95

পাইথন 2: আপনি ব্যবহার করা উচিত mapএবং filterতালিকা comprehensions পরিবর্তে।

তারা "পাইথোনিক" না হওয়া সত্ত্বেও আপনি কেন তাদের পছন্দ করবেন এই উদ্দেশ্যগত কারণ:
তাদের আর্গুমেন্ট হিসাবে ফাংশন / ল্যাম্বডাস প্রয়োজন, যা একটি নতুন সুযোগ প্রবর্তন করে

আমি এটি একাধিকবার কামড়েছি:

for x, y in somePoints:
    # (several lines of code here)
    squared = [x ** 2 for x in numbers]
    # Oops, x was silently overwritten!

তবে পরিবর্তে যদি আমি বলেছিলাম:

for x, y in somePoints:
    # (several lines of code here)
    squared = map(lambda x: x ** 2, numbers)

তাহলে সব ঠিক হয়ে যেত।

আপনি বলতে পারেন যে একই সুযোগে একই পরিবর্তনশীল নামটি ব্যবহার করার জন্য আমি বোকা ছিলাম।

আমি ছিলাম না। কোডটি মূলত ঠিক ছিল - দু'জন xএকই স্কোপে ছিল না।
আমি অভ্যন্তরীণ ব্লকটি কোডের একটি পৃথক বিভাগে স্থানান্তরিত করার পরেই সমস্যাটি উপস্থিত হয়েছিল (পড়ুন: রক্ষণাবেক্ষণের সময় সমস্যা, বিকাশ নয়), এবং আমি এটি আশা করি না।

হ্যাঁ, আপনি যদি কখনও এই ভুলটি না করেন তবে তালিকা উপলব্ধিগুলি আরও মার্জিত।
তবে ব্যক্তিগত অভিজ্ঞতা থেকে (এবং অন্যকেও একই ভুল করতে দেখে) আমি এটিকে পর্যাপ্ত সময়ে দেখেছি যে আমি মনে করি যে এই বাগগুলি আপনার কোডটিতে প্রবেশ করার সময় আপনার যে ব্যথা সহ্য করতে হবে তা লাভজনক নয়।

উপসংহার:

ব্যবহার করুন mapএবং filter। তারা সূক্ষ্ম-থেকে-সনাক্তকরণের সুযোগ-সম্পর্কিত বাগগুলি প্রতিরোধ করে।

সাইড নোট:

আপনার পরিস্থিতির জন্য উপযুক্ত হলে imapএবং ifilter(ইন itertools) ব্যবহার বিবেচনা করতে ভুলবেন না !


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

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

12
আমি দুঃখিত, তবে আপনি এটি লিখেছেন, অজগর 3 দৃশ্যে আসার পরে, এবং উত্তরটি পড়েছে যেমন আপনি পাইথন কোডিংয়ের অন্যথায় অযৌক্তিক স্টাইলের প্রস্তাব দিচ্ছেন কারণ আপনি কাটা-কাটা করার সময় একটি বাগ দ্বারা দংশিত হয়েছিলেন- পেস্টিং কোড আমি কখনই উজ্জ্বল বা অভিজ্ঞ বলে দাবি করি না, আমি ঠিক সম্মত হই না যে সাহসী দাবিটি আপনার কারণে ন্যায়সঙ্গত হয়েছে।
wim

8
@ উইম: হু? পাইথন 2 এখনও প্রচুর জায়গায় ব্যবহৃত হয়, পাইথন 3 উপস্থিত রয়েছে তা পরিবর্তিত হয় না। এবং যখন আপনি বলেন যে "পাইথনটি কয়েক মাসের বেশি ব্যবহার করেছে এমন কারও পক্ষে এটি হুবহু সূক্ষ্ম বাগ নয়" এর এই বাক্যটির আক্ষরিক অর্থ "এটি কেবল অনভিজ্ঞ বিকাশকারীদের উদ্বেগ করে" (স্পষ্টভাবে আপনি নয়)। এবং রেকর্ড, আপনি পরিষ্কারভাবে উত্তর কারণ আমি বলেন পড়তেন না সাহসী যে আমি চলন্ত , কপি না, কোড। অনুলিপি-পেস্ট বাগগুলি ভাষা জুড়ে বেশ সমান। এই ধরণের বাগটি স্কোপিংয়ের কারণে পাইথনের কাছে আরও অনন্য; এটি সূক্ষ্ম এবং সম্পর্কে ভুলে যাওয়া এবং মিস করা সহজ।
user541686

3
এটি এখনও mapএবং / বা স্যুইচ করার যৌক্তিক কারণ নয় filter। যদি কিছু হয় map(lambda x: x ** 2, numbers)তবে আপনার সমস্যা এড়ানোর জন্য সর্বাধিক প্রত্যক্ষ এবং যৌক্তিক অনুবাদ হ'ল জেনারেটর এক্সপ্রেশন নয় list(x ** 2 for x in numbers)যা ফাঁস হয় না, যেমন জেরোজেজে ইতিমধ্যে উল্লেখ করেছেন। মেহরদাদ দেখুন, এতটা ব্যক্তিগতভাবে ডাউনটোট নেবেন না, আমি এখানে আপনার যুক্তির সাথে দৃ with়ভাবে একমত নই।
wim

46

প্রকৃতপক্ষে mapএবং তালিকা অনুধাবন পাইথন 3 ভাষায় বেশ আলাদাভাবে আচরণ করে। নীচের পাইথন 3 প্রোগ্রামটি একবার দেখুন:

def square(x):
    return x*x
squares = map(square, [1, 2, 3])
print(list(squares))
print(list(squares))

আপনি আশা করতে পারেন এটি "[1, 4, 9]" লাইনটি দু'বার মুদ্রণ করবে, তবে পরিবর্তে এটি "[1, 4, 9]" পরে "[]] প্রিন্ট করবে। প্রথমবার আপনি squaresএটি দেখলে মনে হয় তিনটি উপাদানের ক্রম হিসাবে আচরণ করা হয়েছে, তবে দ্বিতীয়বার খালি হিসাবে।

পাইথন 2 ভাষায় mapসরল পুরানো তালিকাটি দেয়, ঠিক তেমনি উভয় ভাষায় তালিকান বোধগম্যতা রয়েছে। কর্সটি হ'ল mapপাইথন 3 এর রিটার্ন মান (এবং imapপাইথন 2 এ) কোনও তালিকা নয় - এটি একটি পুনরাবৃত্তিকারী!

আপনি যখন কোনও তালিকার পুনরাবৃত্তি করেন তার বিপরীতে আপনি যখন কোনও পুনরুক্তি দিয়ে পুনরাবৃত্তি করেন তখন উপাদানগুলি গ্রাস হয়ে যায়। এই কারণেই squaresশেষ print(list(squares))লাইনে খালি দেখাচ্ছে ।

সংক্ষেপ:

  • পুনরাবৃত্তিকারীদের সাথে কথা বলার সময় আপনাকে অবশ্যই মনে রাখতে হবে যে তারা রাষ্ট্রীয় এবং আপনি যখন তাদের অনুসরণ করেন তখন এগুলি পরিবর্তন হয়।
  • তালিকাগুলি আরও অনুমানযোগ্য যেহেতু কেবলমাত্র যখন আপনি সেগুলি স্পষ্টভাবে পরিবর্তিত করেন তখন সেগুলি পরিবর্তন হয়; তারা পাত্রে হয়
  • এবং একটি বোনাস: সংখ্যা, স্ট্রিং এবং টিপলগুলি আরও বেশি অনুমানযোগ্য যেহেতু এগুলি একেবারেই পরিবর্তন করতে পারে না; তারা মান

তালিকা বোধের জন্য এটি সম্ভবত সেরা যুক্তি। পাইথনস মানচিত্র কার্যকরী মানচিত্র নয়, তবে কার্যকরী বাস্তবায়নের পঙ্গু লালচে মাথা step খুব দু: খিত, কারণ আমি সত্যিকারের বোধগম্যকে পছন্দ করি না।
semiomant

@ সেমিওম্যান্ট আমি বলব অলস মানচিত্র (পাইথন 3 এর মতো) উত্সাহিত মানচিত্রের চেয়ে বেশি 'কার্যকরী' (পাইথন 2 এর মতো)। উদাহরণস্বরূপ, হাস্কেলের মানচিত্রটি অলস (ভাল, হাস্কেলের সমস্ত কিছুই অলস ...)। যাইহোক, অলস মানচিত্রটি শৃঙ্খলাবদ্ধ মানচিত্রের জন্য আরও ভাল - যদি আপনার মানচিত্রে মানচিত্রে মানচিত্র প্রয়োগ করা থাকে তবে পাইথন 2-তে প্রতিটি মধ্যবর্তী মানচিত্রের কলগুলির জন্য আপনার একটি তালিকা রয়েছে, তবে পাইথন 3-তে আপনার কেবলমাত্র একটি ফলাফলের তালিকা রয়েছে, সুতরাং এর আরও স্মৃতিশক্তি দক্ষ ।
MnZrK

আমি অনুমান করি যে আমি যা চাই তা mapকোনও ডাটা স্ট্রাকচার তৈরি করতে হয় , এটির পুনরুক্তিকারী নয়। তবে অলস ডাটা স্ট্রাকচারের চেয়ে অলস পুনরুক্তি করা সহজ। চিন্তার জন্য খাদ্য. ধন্যবাদ @ এমএনজেডকে
semiomant

আপনি বলতে চান মানচিত্রটি একটি পুনরাবৃত্তকারীকে ফিরিয়ে দেয়, কোনও পুনরুক্তি প্রদানকারী নয়।
ব্যবহারকারী541686

16

আমি দেখতে পাই যে তালিকার বোধগম্যতাগুলি আমি যা করার চেয়ে চেষ্টা করছি তার থেকে বেশি প্রকাশ করা হয় map- তারা উভয়ই এটি সম্পন্ন করে, তবে প্রাক্তন কোনও জটিল lambdaপ্রকাশ হতে পারে তা বোঝার চেষ্টা করার মানসিক বোঝা বাঁচায় ।

সেখানে কোথাও একটি সাক্ষাত্কারও পাওয়া গেছে (আমি এটি অফহ্যান্ডে খুঁজে পাচ্ছি না) যেখানে lambdaপাইডনকে গ্রহণ করার বিষয়ে গিডো তাঁর কাজ এবং কার্যকরী ফাংশনগুলির তালিকাভুক্ত করেছেন যা তিনি সবচেয়ে আফসোস করেন, তাই আপনি এই যুক্তিটি তৈরি করতে পারেন যে তারা গুণে অ-পাইথোনিক যে.


9
হ্যাঁ, দীর্ঘশ্বাস ফেলুন, তবে পাইথন 3 এ পুরোপুরি ল্যাম্বডা সরিয়ে নেওয়ার গুইডোর আসল অভিপ্রায়টি এর বিরুদ্ধে তদবির করার এক বাধা পেয়েছিল, তাই আমার দৃ st় সমর্থন থাকা সত্ত্বেও তিনি সেটির উপরে ফিরে গেলেন - আহা, অনুমান লাম্বদা অনেকগুলি সিম্পল মামলায় খুব সহজ , কেবলমাত্র সমস্যাটি যখন সিম্পল এর সীমানা ছাড়িয়ে যায় বা কোনও নাম নির্ধারিত হয় (এরপরের ক্ষেত্রে এটি ডিফের একটি মূর্খভাবে আবদ্ধ নকল! -)।
অ্যালেক্স মার্টেলি

1
আপনি যে সাক্ষাত্কারটির বিষয়ে ভাবছেন তা হ'ল এটি: amk.ca/python/writing/gvr-interview , যেখানে গিডো বলেছে "মাঝে মাঝে আমি অবদান গ্রহণে খুব তাড়াতাড়ি এসেছি এবং পরে বুঝতে পেরেছিলাম যে এটি একটি ভুল ছিল। একটি উদাহরণ হবে লাম্বদা ফাংশনগুলির মতো কয়েকটি কার্যকরী প্রোগ্রামিং বৈশিষ্ট্য la ল্যাম্বদা এমন একটি কীওয়ার্ড যা আপনাকে একটি ছোট বেনাম ফাংশন তৈরি করতে দেয়; মানচিত্র, ফিল্টার এবং অন্তর্নির্মিত ক্রিয়াকলাপগুলিকে একটি সিকোয়েন্স টাইপের উপর যেমন একটি তালিকাকে চালিয়ে দেয় reduce "
জে টেলর

3
@ অ্যালেক্স, আপনার কয়েক বছরের অভিজ্ঞতা নেই, তবে আমি ল্যাম্বডাসের চেয়ে অনেক বেশি জটিল তালিকা উপলব্ধি দেখেছি। অবশ্যই, ভাষার বৈশিষ্ট্যগুলিকে অপব্যবহার করা প্রতিরোধ করার পক্ষে সর্বদা একটি কঠিন প্রলোভন। এটি আকর্ষণীয় যে তালিকার বোধগম্যতা (অভিজ্ঞতায়) ল্যাম্বডাসের চেয়ে অপব্যবহারের ঝুঁকির মতো বেশি বলে মনে হয়, যদিও কেন এটি হওয়া উচিত তা আমি নিশ্চিত নই। আমি আরও উল্লেখ করব যে "হোবল্ড" সবসময় খারাপ জিনিস হয় না। "এই লাইনটি যে কাজগুলি করতে পারে" তার সুযোগকে হ্রাস করা কখনও কখনও পাঠকের পক্ষে সহজ করে তুলতে পারে। উদাহরণস্বরূপ, constসি ++ এর মূল শব্দটি এই লাইনগুলি জুড়ে একটি দুর্দান্ত বিজয়।
স্টুয়ার্ট বার্গ

> গাইডো। যা গুয়াদো তার মনের বাইরে রয়েছে তার প্রমাণের আরও একটি অংশ। অবশ্যই lambdaএতটাই খোঁড়া (কোনও বিবৃতি নেই ..) তৈরি করা হয়েছে যে এগুলি যেভাবেই ব্যবহার করা কঠিন এবং সীমিত।
জাভাদবা

16

এখানে একটি সম্ভাব্য কেস রয়েছে:

map(lambda op1,op2: op1*op2, list1, list2)

বনাম:

[op1*op2 for op1,op2 in zip(list1,list2)]

আমি অনুমান করছি জিপ () হ'ল একটি দুর্ভাগ্যজনক এবং অপ্রয়োজনীয় ওভারহেড যদি আপনি মানচিত্রের পরিবর্তে তালিকার বোঝাপড়াগুলি ব্যবহার করার জন্য জোর করেন তবে আপনার তাতে লিপ্ত হওয়া দরকার। কেউ যদি ইতিবাচক বা নেতিবাচক দিক থেকে এটি স্পষ্ট করে তবে দুর্দান্ত হবে।


"[op1 * অপ 2 টি ওপ 1 থেকে, জিপে অপ 2 (তালিকা 1, তালিকা 2)]" | এস / ফর্ম / ফর / এবং আউট জিপ সহ একটি সমতুল তালিকা: (কম পাঠযোগ্য) [তালিকা 1 [i] * তালিকা 2 [i] আই রেঞ্জের জন্য (লেন (তালিকা 1))]
দুর্বল করুন

2
আপনার দ্বিতীয় কোড উদ্ধৃতিতে, "এবং" থেকে "না থেকে" হওয়া উচিত, এবং @ দুর্বলদের মন্তব্যেও। আমি ভেবেছিলাম উপলব্ধিগুলি তালিকাভুক্ত করার জন্য আমি একটি নতুন সিন্ট্যাক্টিকাল পদ্ধতি আবিষ্কার করেছি ... ডার্ন arn
পদার্থবিজ্ঞান

4
খুব দেরিতে মন্তব্য যুক্ত করতে আপনি zipঅলস করতে পারেনitertools.izip
ট্যাকসওয়েল

5
আমি এখনও পছন্দ করি বলে মনে করি map(operator.mul, list1, list2)। এটি খুব সাধারণ বাম দিকের অভিব্যক্তিগুলির উপর যা বোধগম্যতা আঠালো হয়ে যায়।
ইয়ান ভার্নিয়ার

1
আমি বুঝতে পারি নি যে মানচিত্রটি এর ক্রিয়াকলাপের জন্য ইনপুট হিসাবে বিভিন্ন পুনরাবৃত্ত নিতে পারে এবং এইভাবে একটি জিপ এড়াতে পারে।
বিলি

16

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



1
পাইথনের মাল্টিপ্রসেসিং মডিউলটি এটি করে: ডকস.পিথন.আর
রবার্ট এল।

9

পাইথন 3 যেহেতু map()একটি পুনরুক্তিকারী, তাই আপনার যা প্রয়োজন তা মনে রাখতে হবে: একটি পুনরুক্তি বা listবস্তু।

@ অ্যালেক্সমার্তেল্লি যেমন ইতিমধ্যে উল্লিখিত হয়েছে , map()কেবলমাত্র আপনি যদি lambdaফাংশন ব্যবহার না করেন তবে তালিকা বোঝার চেয়ে দ্রুত is

আমি আপনাকে কিছু সময়ের তুলনা উপস্থাপন করব।

পাইথন ৩.৩.২ এবং সিপথন
আমি বৃহস্পিটার নোটবুক এবং বিশেষত %timeitঅন্তর্নির্মিত যাদু কমান্ড
পরিমাপ ব্যবহার করেছি : s == 1000 এমএস == 1000 * 1000 µ এস = 1000 * 1000 * 1000 এনএস

সেটআপ:

x_list = [(i, i+1, i+2, i*2, i-9) for i in range(1000)]
i_list = list(range(1000))

অন্তর্নির্মিত ফাংশন:

%timeit map(sum, x_list)  # creating iterator object
# Output: The slowest run took 9.91 times longer than the fastest. 
# This could mean that an intermediate result is being cached.
# 1000000 loops, best of 3: 277 ns per loop

%timeit list(map(sum, x_list))  # creating list with map
# Output: 1000 loops, best of 3: 214 µs per loop

%timeit [sum(x) for x in x_list]  # creating list with list comprehension
# Output: 1000 loops, best of 3: 290 µs per loop

lambda ফাংশন:

%timeit map(lambda i: i+1, i_list)
# Output: The slowest run took 8.64 times longer than the fastest. 
# This could mean that an intermediate result is being cached.
# 1000000 loops, best of 3: 325 ns per loop

%timeit list(map(lambda i: i+1, i_list))
# Output: 1000 loops, best of 3: 183 µs per loop

%timeit [i+1 for i in i_list]
# Output: 10000 loops, best of 3: 84.2 µs per loop

জেনারেটর এক্সপ্রেশনের মতো জিনিস রয়েছে, দেখুন পিইপি -0289 । সুতরাং আমি ভেবেছিলাম এটি তুলনার সাথে যুক্ত করা কার্যকর হবে

%timeit (sum(i) for i in x_list)
# Output: The slowest run took 6.66 times longer than the fastest. 
# This could mean that an intermediate result is being cached.
# 1000000 loops, best of 3: 495 ns per loop

%timeit list((sum(x) for x in x_list))
# Output: 1000 loops, best of 3: 319 µs per loop

%timeit (i+1 for i in i_list)
# Output: The slowest run took 6.83 times longer than the fastest. 
# This could mean that an intermediate result is being cached.
# 1000000 loops, best of 3: 506 ns per loop

%timeit list((i+1 for i in i_list))
# Output: 10000 loops, best of 3: 125 µs per loop

আপনার listঅবজেক্ট দরকার :

এটি কাস্টম ফাংশন হলে তালিকা বোধগম্য ব্যবহার করুন, list(map())বিল্টিন ফাংশন থাকলে ব্যবহার করুন

আপনার listঅবজেক্টের দরকার নেই , আপনার কেবল পুনরাবৃত্তিযোগ্য দরকার:

সর্বদা ব্যবহার map()!


1

আমি একটি অবজেক্টের পদ্ধতিটি আহ্বানের জন্য তিনটি পদ্ধতির তুলনায় একটি দ্রুত পরীক্ষা চালিয়েছি। সময়ের পার্থক্য, এক্ষেত্রে, নগণ্য এবং প্রশ্নে কার্যকরী বিষয় (@ অ্যালেক্স মার্তেলির প্রতিক্রিয়া দেখুন )। এখানে, আমি নিম্নলিখিত পদ্ধতিগুলির দিকে নজর রেখেছি:

# map_lambda
list(map(lambda x: x.add(), vals))

# map_operator
from operator import methodcaller
list(map(methodcaller("add"), vals))

# map_comprehension
[x.add() for x in vals]

তালিকার আকার বাড়ানোর জন্য আমি valsউভয় পূর্ণসংখ্যার (পাইথন int) এবং ভাসমান পয়েন্ট সংখ্যা (পাইথন float) এর তালিকাগুলি (ভেরিয়েবলে সঞ্চিত ) দেখলাম । নিম্নলিখিত ডামি শ্রেণি DummyNumবিবেচনা করা হয়:

class DummyNum(object):
    """Dummy class"""
    __slots__ = 'n',

    def __init__(self, n):
        self.n = n

    def add(self):
        self.n += 5

বিশেষত, addপদ্ধতি। __slots__অ্যাট্রিবিউট পাইথন একটি সহজ অপ্টিমাইজেশান, মোট মেমরি শ্রেণী (বৈশিষ্ট্যাবলী) প্রয়োজনীয় সংজ্ঞায়িত করতে মেমরির আকার হ্রাস করুন। এখানে ফলস্বরূপ প্লটগুলি রয়েছে।

পাইথন অবজেক্ট পদ্ধতিগুলির ম্যাপিংয়ের কার্যকারিতা

যেমন আগেই বলা হয়েছে, ব্যবহৃত কৌশলটি একটি ন্যূনতম পার্থক্য তৈরি করে এবং আপনার এমনভাবে কোড করা উচিত যা আপনার কাছে সবচেয়ে পাঠযোগ্য বা বিশেষ পরিস্থিতিতে। এই ক্ষেত্রে, তালিকা উপলব্ধি ( map_comprehensionকৌশল) কোনও বস্তুতে বিশেষত সংক্ষিপ্ত তালিকা সহ উভয় প্রকারের সংযোজনের জন্য দ্রুততম।

প্লট এবং ডেটা উত্পন্ন করতে উত্স হিসাবে ব্যবহৃত এই পেস্টবিনটি দেখুন ।


1
যেমন ইতিমধ্যে অন্যান্য উত্তরে ব্যাখ্যা করা হয়েছে, mapকেবল তখনই দ্রুত হয় যদি ফাংশনটিকে একইভাবে বলা হয় (যেমন [*map(f, vals)]বনাম [f(x) for x in vals])। তাই list(map(methodcaller("add"), vals))দ্রুত চেয়ে [methodcaller("add")(x) for x in vals]mapদ্রুত নাও হতে পারে যখন লুপিং সহযোগীর একটি ভিন্ন কলিং পদ্ধতি যে কিছু উপরি এড়াতে পারেন ব্যবহার (যেমন x.add()এড়াতে methodcallerবা ল্যামডা অভিব্যক্তি ওভারহেড)। এই নির্দিষ্ট পরীক্ষার ক্ষেত্রে [*map(DummyNum.add, vals)]দ্রুত হবে (কারণ DummyNum.add(x)এবং x.add()মূলত একই পারফরম্যান্স রয়েছে)।
GZ0

1
উপায় দ্বারা, সুস্পষ্ট list()কলগুলি তালিকা বোধের তুলনায় কিছুটা ধীর। ন্যায্য তুলনার জন্য আপনাকে লিখতে হবে [*map(...)]
GZ0

@ GZ0 দুর্দান্ত প্রতিক্রিয়া জন্য ধন্যবাদ! সব বোঝা যায়, এবং আমি জানতাম না যে list()কলগুলি ওভারহেড বাড়িয়েছে। উত্তরগুলি পড়ার জন্য আরও বেশি সময় ব্যয় করা উচিত ছিল। আমি এই পরীক্ষাগুলি ন্যায্য তুলনার জন্য আবার চালাব, তবে তফাত কম হতে পারে।
ক্রাইমাইকেল

0

আমি বিবেচনা যে সবচেয়ে Pythonic উপায় পরিবর্তে একটি তালিকা ধী ব্যবহার করা mapএবং filter। কারণ তালিকা comprehensions চেয়ে পরিষ্কার হয় mapএবং filter

In [1]: odd_cubes = [x ** 3 for x in range(10) if x % 2 == 1] # using a list comprehension

In [2]: odd_cubes_alt = list(map(lambda x: x ** 3, filter(lambda x: x % 2 == 1, range(10)))) # using map and filter

In [3]: odd_cubes == odd_cubes_alt
Out[3]: True

আপনি দেখতে হিসাবে, একটি বোধগম্যতা lambdaহিসাবে অতিরিক্ত এক্সপ্রেশন প্রয়োজন হয় না map। তদ্ব্যতীত, একটি বোধগম্যতা সহজেই ফিল্টারিং করতে দেয় , যখন ফিল্টারিংয়ের অনুমতি mapপ্রয়োজন filter


0

আমি @ অ্যালেক্স-মার্তেলির মাধ্যমে কোডটি চেষ্টা করেছিলাম তবে কিছু ত্রুটি খুঁজে পেয়েছি

python -mtimeit -s "xs=range(123456)" "map(hex, xs)"
1000000 loops, best of 5: 218 nsec per loop
python -mtimeit -s "xs=range(123456)" "[hex(x) for x in xs]"
10 loops, best of 5: 19.4 msec per loop

আমার কোড থেকে স্পষ্ট যেমন তালিকা বোঝাপড়াটি ব্যবহার করা হয় তখন অনেক বড় ব্যাপ্তির জন্যও মানচিত্র একই পরিমাণে সময় নেয়। সুতরাং "অপার্থিব" হিসাবে বিবেচিত হওয়া ছাড়াও আমি মানচিত্রের ব্যবহার সম্পর্কিত কোনও পারফরম্যান্স সমস্যার মুখোমুখি হইনি।


3
এটি একটি খুব পুরানো প্রশ্ন এবং আপনি যে উত্তরটি উল্লেখ করছেন খুব সম্ভবত পাইথন 2 এর উল্লেখে লেখা হয়েছিল, যেখানে mapএকটি তালিকা ফিরে আসে। পাইথন 3-এ, mapঅলসভাবে মূল্যায়ন করা হয়, তাই কেবল কল করা mapকোনও নতুন তালিকার উপাদানগুলির গণনা করে না, সুতরাং আপনি কেন এইরকম স্বল্প সময় পান।
কেয়া 3

আমি মনে করি আপনি পাইথন ৩.x ব্যবহার করছেন আপনি যখন এই প্রশ্নটি জিজ্ঞাসা করেছিলেন পাইথন 3 সম্প্রতি প্রকাশিত হয়েছিল এবং পাইথন ২.x খুব মান।
টিমোথিউজম্যান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.