অজগর মানচিত্র এবং অন্যান্য কার্যকরী সরঞ্জাম ব্যবহার করে


127

এটি বেশ n00bish, তবে আমি পাইথনে ফাংশনাল প্রোগ্রামিং শিখতে / বোঝার চেষ্টা করছি। নিম্নলিখিত কোড:

foos = [1.0,2.0,3.0,4.0,5.0]
bars = [1,2,3]

def maptest(foo, bar):
    print foo, bar

map(maptest, foos, bars)

সৃষ্টি করে:

1.0 1
2.0 2
3.0 3
4.0 None
5.0 None

প্র: লুপগুলি বাদ দিয়ে নিম্নলিখিত উত্পাদন করার জন্য অজগরটিতে মানচিত্র বা অন্য কোনও কার্যকরী সরঞ্জাম ব্যবহার করার কোনও উপায় আছে কি?

1.0 [1,2,3]
2.0 [1,2,3]
3.0 [1,2,3]
4.0 [1,2,3]
5.0 [1,2,3]

যেমন পার্শ্ব নোট যেমন foo এবং বারের মধ্যে নির্ভরতা থাকে তবে বাস্তবায়ন কীভাবে পরিবর্তিত হবে। যেমন

foos = [1.0,2.0,3.0,4.0,5.0]
bars = [1,2,3,4,5]

এবং মুদ্রণ:

1.0 [2,3,4,5]
2.0 [1,3,4,5]
3.0 [1,2,4,5]
...

পিএস: লুপ এবং / অথবা জেনারেটর যদি হয় তবে কীভাবে নির্দ্বিধায় এটি করতে হয় তা আমি জানি তবে আমি কীভাবে কার্যক্ষম সরঞ্জামগুলি ব্যবহার করে এটি অর্জন করতে শিখতে চাই। এটি ম্যাপেস্টেস্টে আইএফ স্টেটমেন্ট যুক্ত করার বা ম্যাপটেস্টের মধ্যে অভ্যন্তরীণভাবে বারে আরও একটি ফিল্টার মানচিত্র প্রয়োগ করার ঘটনা?


ধন্যবাদ বন্ধুরা. আমার অবশ্যই স্বীকার করতে হবে যে আমি পাইথনের মাধ্যমে ফাংশনাল প্রোগ্রামিংয়ের ধারণাগুলি শেখার চেষ্টা করছি।

1
এটির জন্য এখানে একটি সুন্দর টিউটোরিয়াল: স্বপ্নসিয়োসফট
রকি পুলি

উত্তর:


54

সবচেয়ে সহজ উপায় হ'ল barsবিভিন্ন ফাংশনটি অতিক্রম না করা , তবে এখান থেকে সরাসরি এটি অ্যাক্সেস করা maptest:

foos = [1.0,2.0,3.0,4.0,5.0]
bars = [1,2,3]

def maptest(foo):
    print foo, bars

map(maptest, foos)

আপনার আসল maptestফাংশনটির সাথে আপনি এখানে ল্যাম্বডা ফাংশনটিও ব্যবহার করতে পারেন map:

map((lambda foo: maptest(foo, bars)), foos)

বারগুলি তালিকা থেকে আসে যখন
খারাপটি

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

3
প্রিয় স্ট্যাক ওভারফ্লো, যেহেতু আপনি প্রশ্নগুলি বন্ধ করতে চান এবং মাঝারিভাবে ভারী, তাই আপনি কেন এই প্রশ্নটির উত্তর হিসাবে চিহ্ন না দিয়ে উত্তরটিকে সঠিক প্রতিক্রিয়া হিসাবে চিহ্নিত করেন? শুভেচ্ছা, আমাদের।
বাহাদির ক্যামবেল

1
@ আইমেজ_ডোক্টর, এফপিতে এটি বিশ্বব্যাপী ধ্রুবক অ্যাক্সেস করা পুরোপুরি ঠিক আছে (সেখানে নুলারি ফাংশন হিসাবে বিবেচনা করা হয়)
পিটার কে

1
@ বাহাদির ক্যামবেল স্ট্যাক ওভারফ্লো সংযোজন কখনও কখনও ভারী হাতে হতে পারে তবে চেকমার্কটি সর্বদা, এবং সর্বদা, ওপি'র অন্তর্ভুক্ত।
wizzwizz4

194

আপনি কি অন্যান্য কার্যকরী ভাষার সাথে পরিচিত? অর্থ্যাৎ আপনি কীভাবে অজগরটি কার্যকরী প্রোগ্রামিং করেন তা শেখার চেষ্টা করছেন, বা আপনি ফাংশনাল প্রোগ্রামিং এবং অজগরটিকে বাহন হিসাবে ব্যবহার করার বিষয়ে শেখার চেষ্টা করছেন?

এছাড়াও, আপনি কি তালিকার বোধগম্যতা বোঝেন?

map(f, sequence)

এর সাথে সরাসরি সমতুল্য (*):

[f(x) for x in sequence]

প্রকৃতপক্ষে, আমি মনে করি map()একবার অযৌক্তিক হিসাবে অজগর 3.0 থেকে অপসারণের পরিকল্পনা করা হয়েছিল (এটি হয়নি)।

map(f, sequence1, sequence2)

বেশিরভাগ সমতুল্য:

[f(x1, x2) for x1, x2 in zip(sequence1, sequence2)]

(ক্রমগুলি বিভিন্ন দৈর্ঘ্যের যেখানে কেস পরিচালনা করে তার মধ্যে একটি পার্থক্য রয়েছে As যেমন আপনি দেখেছেন, map()সিকোয়েন্সগুলির কোনওটি শেষ হয়ে গেলে কোনওটিই পূরণ করে না, যখন zip()সংক্ষিপ্ততম ক্রম বন্ধ হয়ে যায় তখন থামে)

সুতরাং, আপনার নির্দিষ্ট প্রশ্নের সমাধানের জন্য, আপনি ফলাফলটি চেষ্টা করার চেষ্টা করছেন:

foos[0], bars
foos[1], bars
foos[2], bars
# etc.

আপনি একটি ফাংশন লিখে এটি করতে পারেন যা একক যুক্তি গ্রহণ করে এবং প্রিন্ট করে বারগুলি অনুসরণ করে:

def maptest(x):
     print x, bars
map(maptest, foos)

বিকল্পভাবে, আপনি দেখতে এমন একটি তালিকা তৈরি করতে পারেন:

[bars, bars, bars, ] # etc.

এবং আপনার মূল মানচিত্রটি ব্যবহার করুন:

def maptest(x, y):
    print x, y

এটি করার একটি উপায় হ'ল সুস্পষ্টভাবে তালিকাটি আগে তৈরি করা হবে:

barses = [bars] * len(foos)
map(maptest, foos, barses)

বিকল্পভাবে, আপনি itertoolsমডিউলটি টানতে পারেন । itertoolsঅনেক চতুর ফাংশন রয়েছে যা আপনাকে পাইথনে ফাংশনাল স্টাইলে অলস-মূল্যায়ন প্রোগ্রামিং করতে সহায়তা করে। এই ক্ষেত্রে, আমরা চাই itertools.repeat, যা এটির পুনরাবৃত্তি করার সাথে সাথে তার যুক্তি অনির্দিষ্টকালের জন্য আউটপুট করবে। এই শেষ ঘটনাটির অর্থ এই যে আপনি যদি করেন:

map(maptest, foos, itertools.repeat(bars))

আপনি অন্তহীন আউটপুট পাবেন, যেহেতু map()ততক্ষণ আর্গুমেন্টগুলির মধ্যে একটি এখনও আউটপুট উত্পাদন করে চলে। যাইহোক, itertools.imapঠিক যেমন map(), তবে সংক্ষিপ্ত পুনরাবৃত্তিযোগ্য স্টপগুলির সাথে সাথেই থেমে যায়।

itertools.imap(maptest, foos, itertools.repeat(bars))

আশাকরি এটা সাহায্য করবে :-)

(*) অজগর 3.0 এ এটি কিছুটা আলাদা। সেখানে, মানচিত্র () মূলত একটি জেনারেটর এক্সপ্রেশন প্রদান করে।


সুতরাং, আমি কি সঠিকভাবে বুঝতে পারি যে, মানচিত্রের বিপরীতে itertools.imap(f, sequence1, sequence2)সত্যিকারের সমান [f(x1, x2) for x1, x2 in zip(sequence1, sequence2)]?
জন কোম্বস

কিছুটা পরীক্ষা করে দেখছি, এটি একটি itertools.imap অবজেক্ট ফিরিয়ে দেয়, তাই সম্ভবত এটি আরও 'সমতুল্য' হতে পারে:list(itertools.imap(f, sequence1, sequence2))
জন কোম্বস

এটি অনুমোদিত উত্তর হওয়া উচিত।
রব গ্রান্ট

30

আপনি যে সমাধানটি সন্ধান করছেন তা এখানে:

>>> foos = [1.0, 2.0, 3.0, 4.0, 5.0]
>>> bars = [1, 2, 3]
>>> [(x, bars) for x in foos]
[(1.0, [1, 2, 3]), (2.0, [1, 2, 3]), (3.0, [1, 2, 3]), (4.0, [1, 2, 3]), (5.0, [
1, 2, 3])]

আমি [(x, bars) for x in foos]ম্যাপ ব্যবহার করে একটি তালিকা বোধ ( অংশ) ব্যবহার করার পরামর্শ দেব কারণ এটি প্রতিটি পুনরাবৃত্তির (যা খুব তাৎপর্যপূর্ণ হতে পারে) কোনও ফাংশন কলের ওভারহেডকে এড়িয়ে চলে। আপনি যদি কেবল এটি লুপের জন্য ব্যবহার করতে চলেছেন তবে আপনি একটি জেনারেটর বোঝাপড়া ব্যবহার করে আরও ভাল গতি পাবেন:

>>> y = ((x, bars) for x in foos)
>>> for z in y:
...     print z
...
(1.0, [1, 2, 3])
(2.0, [1, 2, 3])
(3.0, [1, 2, 3])
(4.0, [1, 2, 3])
(5.0, [1, 2, 3])

পার্থক্যটি হ'ল জেনারেটর উপলব্ধিটি অলসভাবে লোড হয়

এই মন্তব্যের জবাবে আপডেট করুন:

অবশ্যই আপনি জানেন, আপনি বারগুলি অনুলিপি করেন না, সমস্ত এন্ট্রি একই বারের তালিকা। সুতরাং আপনি যদি এগুলির যে কোনও একটিতে (মূল বারগুলি সহ) সংশোধন করেন তবে আপনি সেগুলি সমস্ত সংশোধন করেন।

আমি মনে করি এটি একটি বৈধ পয়েন্ট। এর দুটি সমাধান রয়েছে যা আমি ভাবতে পারি। সবচেয়ে দক্ষ সম্ভবত এইরকম কিছু:

tbars = tuple(bars)
[(x, tbars) for x in foos]

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

from copy import copy
[(x, copy(bars)) for x in foos]

যাইহোক, মেমরির ব্যবহার এবং গতির ক্ষেত্রে এটি কিছুটা ব্যয়বহুল হতে পারে, সুতরাং আমি যদি এগুলির প্রতিটিতে যুক্ত না হয় তবে আমি এর বিরুদ্ধে সুপারিশ করব।


1
অবশ্যই আপনি জানেন, আপনি বারগুলি অনুলিপি করেন না, সমস্ত এন্ট্রি একই বারের তালিকা। সুতরাং আপনি যদি এগুলির যে কোনও একটিতে (মূল বারগুলি সহ) সংশোধন করেন তবে আপনি সেগুলি সমস্ত সংশোধন করেন।
ভের্টেক

20

কার্যকরী প্রোগ্রামিং পার্শ্ব-প্রভাব-মুক্ত কোড তৈরি সম্পর্কে।

মানচিত্র একটি কার্যকরী তালিকা রূপান্তর বিমূর্ততা। আপনি এটি কোনও কিছুর ক্রম নিতে এবং এটিকে অন্য কোনও কিছুর অনুক্রমে পরিণত করতে ব্যবহার করেন।

আপনি এটির পুনরুক্তিকারী হিসাবে ব্যবহার করার চেষ্টা করছেন। এটা করবেন না। :)

আপনি যে তালিকাটি চান তা তৈরি করতে আপনি কীভাবে মানচিত্র ব্যবহার করতে পারেন তার একটি উদাহরণ এখানে। আরও সংক্ষিপ্ত সমাধান রয়েছে (আমি কেবল উপলব্ধিগুলি ব্যবহার করব) তবে এটি আপনাকে কী মানচিত্রটি আরও ভাল করে তা বুঝতে সহায়তা করবে:

def my_transform_function(input):
    return [input, [1, 2, 3]]

new_list = map(my_transform, input_list)

এই মুহুর্তে লক্ষ্য করুন, আপনি কেবল একটি ডেটা ম্যানিপুলেশন করেছেন। এখন আপনি এটি মুদ্রণ করতে পারেন:

for n,l in new_list:
    print n, ll

- আপনি 'লুপ ছাড়া' বলতে চাইছেন তা আমি নিশ্চিত নই। এফপি লুপগুলি এড়ানো সম্পর্কে নয় (আপনি তালিকার প্রতিটি আইটেম প্রত্যেকে না দেখে পরীক্ষা করতে পারবেন না)। এটি পার্শ্ব-প্রতিক্রিয়া এড়াতে, এভাবে কম বাগ লিখতে।



11
import itertools

foos=[1.0, 2.0, 3.0, 4.0, 5.0]
bars=[1, 2, 3]

print zip(foos, itertools.cycle([bars]))

এটি সবচেয়ে সহজ এবং সঠিকভাবে কার্যকরী। দয়া করে এটি উত্তর হিসাবে গ্রহণ করুন
ফোয়ো আরকার লুইন

1
এটি কেবল কোড। এর কোন ব্যাখ্যা নেই। অনেক ব্যবহারকারী এই উত্তরটির অর্থ কী বুঝতে পারে না। @ ফিওআরকারলউইন
প্রোগ্রামফাস্ট

6

map(function, *sequences)ফাংশনটির পরামিতিগুলির একটি সংক্ষিপ্ত বিবরণ এখানে :

  • function আপনার ফাংশনের নাম।
  • sequencesক্রমগুলির যে কোনও সংখ্যা যা সাধারণত তালিকা বা টিপলস হয়। mapতাদের একসাথে পুনরাবৃত্তি এবং বর্তমান মান দিতে হবে function। সিক্যুয়েন্সগুলির সংখ্যাটি আপনার ফাংশনের সাথে পরামিতির সংখ্যার সমান হওয়া উচিত।

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

অন্যরা যেমন পরামর্শ দিয়েছে তেমনি বৈশ্বিক পরিবর্তনশীল বা তালিকা বোঝার মতো কাজের মতো ব্যবহার করুন।


0

এটি কি এটা করবে?

foos = [1.0,2.0,3.0,4.0,5.0]
bars = [1,2,3]

def maptest2(bar):
  print bar

def maptest(foo):
  print foo
  map(maptest2, bars)

map(maptest, foos)

1
আপনি ম্যাপেস্টেস্ট 2 () এর জন্য 'বার' এর মতো কিছু জন্য পরমকে কল করতে চাইতে পারেন। একক barশব্দটি বোঝায় যে এটি একটি পুনরাবৃত্তি মান পাচ্ছে, যখন আপনি আসলে পুরো তালিকাটি চান।
নিখিল চেলিয়াহ

1
এটি আসলে আমি বিশ্বাস করি এমন একটি পুনরাবৃত্ত মান পাচ্ছে।
ক্রিস

0

এটি সম্পর্কে:

foos = [1.0,2.0,3.0,4.0,5.0]
bars = [1,2,3]

def maptest(foo, bar):
    print foo, bar

map(maptest, foos, [bars]*len(foos))
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.