পাইথন 3 এ কীভাবে ফিল্টার, মানচিত্র এবং হ্রাস করতে হয়


321

filter, map, এবং reduceপাইথন 2. এখানে পুরোপুরি কাজ একটি উদাহরণ রয়েছে:

>>> def f(x):
        return x % 2 != 0 and x % 3 != 0
>>> filter(f, range(2, 25))
[5, 7, 11, 13, 17, 19, 23]

>>> def cube(x):
        return x*x*x
>>> map(cube, range(1, 11))
[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]

>>> def add(x,y):
        return x+y
>>> reduce(add, range(1, 11))
55

তবে পাইথন 3 এ, আমি নিম্নলিখিত ফলাফলগুলি পেয়েছি:

>>> filter(f, range(2, 25))
<filter object at 0x0000000002C14908>

>>> map(cube, range(1, 11))
<map object at 0x0000000002C82B70>

>>> reduce(add, range(1, 11))
Traceback (most recent call last):
  File "<pyshell#8>", line 1, in <module>
    reduce(add, range(1, 11))
NameError: name 'reduce' is not defined

যদি কেউ আমাকে কেন এটি হয় তা ব্যাখ্যা করতে পারলে আমি প্রশংসা করব।

আরও স্পষ্টতার জন্য কোডের স্ক্রিনশট:

পাইথন 2 এবং 3 পাশাপাশি পাশাপাশি আইডিএল সেশন


1
সংক্ষেপে, তালিকাটি কেবলমাত্র ডেটাটাইপ নয়। আপনি যদি একটি তালিকা চান, আপনি একটি তালিকা চান বলুন। তবে বেশিরভাগ ক্ষেত্রেই আপনি অন্যভাবে কিছু চান।
ভিকি

উত্তর:


346

পাইথন In.০-এ নতুন কী পরিবর্তন হয়েছে সে সম্পর্কে আপনি পড়তে পারেন । যখন আপনি 2.x থেকে 3.x এ চলেছেন তখন আপনার এটি পুরোপুরি পড়তে হবে যেহেতু প্রচুর পরিবর্তন হয়েছে।

এখানে পুরো উত্তর ডকুমেন্টেশন থেকে উদ্ধৃতি।

তালিকার পরিবর্তে ভিউ এবং আইট্রেটার

কিছু সুপরিচিত API গুলি আর তালিকা ফেরত দেয় না:

  • [...]
  • map()এবং filter()পুনরাবৃত্তি পুনরায়। আপনার যদি সত্যিই একটি তালিকার দরকার হয় list(map(...))তবে দ্রুত সমাধান উদাহরণস্বরূপ , তবে একটি ভাল ফিক্সটি প্রায়শই একটি তালিকা বোঝার জন্য ব্যবহার করা হয় (বিশেষত যখন মূল কোডটি ল্যাম্বডা ব্যবহার করে), বা কোডটি পুনরায় লেখায় যাতে এটির কোনও তালিকার প্রয়োজন হয় না। map()ফাংশনটির পার্শ্ব প্রতিক্রিয়াগুলির জন্য বিশেষত কৌতুকপূর্ণ ; সঠিক রূপান্তরটি হ'ল নিয়মিত forলুপ ব্যবহার করা (যেহেতু একটি তালিকা তৈরি করা কেবল অপচয় নয়)।
  • [...]

Builtins

  • [...]
  • সরানো হয়েছে reduce()। আপনার functools.reduce()যদি সত্যিই এটির প্রয়োজন হয় তা ব্যবহার করুন ; তবে, 99 শতাংশ সময় একটি সুস্পষ্ট forলুপ বেশি পঠনযোগ্য।
  • [...]

21
যোগ করা হচ্ছে list(map(...) সর্বত্র .. জগতের মধ্যে কিভাবে যে পাঠযোগ্যতা সাহায্য .. pythonপ্রগতিশীল / ক্রিয়ামূলক combinators প্রয়োগের স্ট্রিমিং হ্যান্ডেল বলে মনে হচ্ছে না পারবেন না। অন্যান্য ভাষাগুলি আমি একের পর এক সংগ্রহের বিরুদ্ধে কয়েক ডজন অপারেশন চেইন করতে পারি এবং এটি পাঠযোগ্য। এখানে? আপনি কি চান - এক ডজন পথ নেস্টেড in??
জাভাদবা

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

2
@ জাভাদ্ব্বা আপনি কি কোনও "স্ট্রিমিং অ্যাপ্লিকেশন" তে নিশ্চিত যে আপনার কলটি একেবারেই যুক্ত করা দরকার list? আমি ভেবেছিলাম "স্ট্রিমিং" এর অর্থ হ'ল "কোনও তালিকাই তৈরি হয় না; পরবর্তীটিতে যাওয়ার আগে ইনপুটটির প্রতিটি উপাদানকে পুরোপুরি প্রক্রিয়া করুন"।
অনিবার্য রাত

@ ম্যাট্রিক্সম্যান অ্যাটায়ার সার্ভিস আপনি যদি নিশ্চিত হন যে পাইথন 2 আচরণ আপনার যা প্রয়োজন তা হ'ল, আপনি সর্বদা কেবল নতুন সংজ্ঞা দিতে পারেন map
অনিবার্য রাত

6
আমি এখনও বুঝতে পারি না যে কীভাবে একটি পঠনযোগ্যতার যুক্তি এমন পরিবর্তন আনতে পরিচালিত করে। এটি যদি পারফরম্যান্সের কারণে হয় তবে আমি বুঝতে পারি ...
মিনাতো

86

এর কার্যকারিতা mapএবং filterইচ্ছাকৃতভাবে পুনরাবৃত্তকারীদের ফেরত পাঠানো হয়েছিল এবং হ্রাসটি একটি অন্তর্নির্মিত এবং স্থাপন করা থেকে সরানো হয়েছিল functools.reduce

সুতরাং, এর জন্য filterএবং এর আগে আপনি ফলাফলগুলি দেখতে mapএগুলি এগুলি মুড়িয়ে list()রাখতে পারেন।

>>> def f(x): return x % 2 != 0 and x % 3 != 0
...
>>> list(filter(f, range(2, 25)))
[5, 7, 11, 13, 17, 19, 23]
>>> def cube(x): return x*x*x
...
>>> list(map(cube, range(1, 11)))
[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]
>>> import functools
>>> def add(x,y): return x+y
...
>>> functools.reduce(add, range(1, 11))
55
>>>

এখনই সুপারিশটি হ'ল আপনি নিজের মানচিত্রের ব্যবহার প্রতিস্থাপন করুন এবং জেনারেটর এক্সপ্রেশন বা তালিকা বোঝার সাথে ফিল্টার করুন। উদাহরণ:

>>> def f(x): return x % 2 != 0 and x % 3 != 0
...
>>> [i for i in range(2, 25) if f(i)]
[5, 7, 11, 13, 17, 19, 23]
>>> def cube(x): return x*x*x
...
>>> [cube(i) for i in range(1, 11)]
[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]
>>>

তারা বলে যে লুপগুলির জন্য 99 শতাংশ সময় হ্রাস করার চেয়ে পড়ার পক্ষে সহজ তবে আমি কেবল এর সাথেই থাকি functools.reduce

সম্পাদনা করুন : গুয়াদো ভ্যান রসম রচিত Py৯ শতাংশ চিত্রটি সরাসরি ওয়াটস ইন ইন পাইথন 3.0.০ পৃষ্ঠা থেকে টানা হয়েছে ।


5
তালিকার বোধগম্যতায় আপনার অতিরিক্ত ফাংশন তৈরি করার দরকার নেই। স্রেফ ব্যবহার করুন[i*i*i for i in range(1,11)]
জিয়াও

2
আপনি একেবারে সঠিক। ফিল্টার / মানচিত্রের উদাহরণগুলির সাথে সাদৃশ্যপূর্ণ রাখতে আমি ফাংশনটিকে তালিকা বোধের উদাহরণগুলিতে রেখেছি।
জোশুয়া ডি।

5
i ** 3 হ'ল I * i * i এর সমতুল্য
ব্রীজার

5
@ ব্রিজার আসলে i**3কল করবে i.__pow__(3)এবং i*i*i i.__mul__(i).__mul__(i)(বা এরকম কিছু)। Ints এর সাথে কিছু আসে যায় না তবে ন্যালি নম্বর / কাস্টম ক্লাসের সাথে এটি বিভিন্ন ফলাফলও পেতে পারে।
প্রতিশব্দ

1
আমি লক্ষ করেছি যে যখনই আমরা শুনি যে "গাইডো সিদ্ধান্ত নিয়েছে এক্স" যে ব্যথা হওয়ার সম্ভাবনা রয়েছে। এটি একটি দুর্দান্ত উদাহরণ: অজগরটিতে ইতিমধ্যে ভারবজ list(list(list(.. )))ছিল যা করা ।
জাভাদবা

12

অন্যান্য উত্তরের সংযোজন হিসাবে, এটি একটি প্রসঙ্গ পরিচালকের জন্য সূক্ষ্ম ব্যবহারের ক্ষেত্রে শোনাচ্ছে যা এই ফাংশনগুলির নামগুলি পুনরায় ম্যাপ করবে যা একটি তালিকা ফিরে আসে reduceএবং বিশ্বব্যাপী নেমস্পেসে প্রবর্তন করে।

একটি দ্রুত বাস্তবায়ন এর মত দেখতে পারে:

from contextlib import contextmanager    

@contextmanager
def noiters(*funcs):
    if not funcs: 
        funcs = [map, filter, zip] # etc
    from functools import reduce
    globals()[reduce.__name__] = reduce
    for func in funcs:
        globals()[func.__name__] = lambda *ar, func = func, **kwar: list(func(*ar, **kwar))
    try:
        yield
    finally:
        del globals()[reduce.__name__]
        for func in funcs: globals()[func.__name__] = func

এমন দেখতে এমন ব্যবহারের সাথে:

with noiters(map):
    from operator import add
    print(reduce(add, range(1, 20)))
    print(map(int, ['1', '2']))

কোন মুদ্রণ:

190
[1, 2]

শুধু আমার 2 সেন্ট :-)


1
pythonএকটি ভাষা হিসেবে একটি জগাখিচুড়ি - কিন্তু এটি চমৎকার লাইব্রেরী বনাম ভাল আছে: numpy, pandas, statsmodelsএবং বন্ধুদের .. আমি সুবিধার লাইব্রেরি buliding হয়েছে মত আপনি এখানে দেখা মাতৃভাষা বেদনা কমাতে - কিন্তু শক্তি হারিয়ে ফেলেছে এবং এখন না চেষ্টা করেছি একটি data.frame/ datatable, বা থেকে দূরে বিপথগামী xarray। কিন্তু চেষ্টা করার জন্য
কুডোস

7

যেহেতু reduceপাইথন 3 থেকে বিল্ট ইন ফাংশনটি থেকে পদ্ধতিটি সরানো হয়েছে, তাই আপনার কোডটিতে আমদানি করতে ভুলবেন না functools। নীচের কোড স্নিপেট দেখুন।

import functools
my_list = [10,15,20,25,35]
sum_numbers = functools.reduce(lambda x ,y : x+y , my_list)
print(sum_numbers)

2

এখানে ফিল্টার, মানচিত্র এবং ফাংশন হ্রাস এর উদাহরণ রয়েছে।

সংখ্যা = [10,11,12,22,34,43,54,34,67,87,88,98,99,87,44,66]

//ছাঁকনি

বিজোড় সংখ্যা = তালিকা (ফিল্টার (ল্যাম্বদা এক্স: x% 2! = 0, সংখ্যা))

মুদ্রণ (oddNumbers)

// ম্যাপ

গুণকফত = তালিকা (মানচিত্র (ল্যাম্বদা এক্স: এক্স * 2, সংখ্যা))

মুদ্রণ (multiplyOf2)

// কমাতে

হ্রাস ফাংশন, যেহেতু এটি সাধারণত ব্যবহৃত হয় না, পাইথন 3 এর অন্তর্নির্মিত ফাংশনগুলি থেকে সরানো হয়েছিল এটি এখনও ফান্টুলস মডিউলে পাওয়া যায়, তাই আপনি এটি করতে পারেন:

ফান্টুল থেকে আমদানি হ্রাস করুন

যোগফলগুলি = হ্রাস করুন (ল্যাম্বদা এক্স, y: x + y, সংখ্যা)

মুদ্রণ (sumOfNumbers)


ফর্ম্যাট করার জন্য আপনাকে একটি +1 প্রদান করা হচ্ছে
বায়রন কোটিসি

0

মানচিত্র, ফিল্টার এবং হ্রাস করার অন্যতম সুবিধা হ'ল আপনি যখন কিছু জটিল করে একসাথে তাদের "চেইন" করেন তখন এগুলি কতটা সচেতন হয়। যাইহোক, অন্তর্নির্মিত বাক্য গঠনটি যথাযথ নয় এবং সবগুলি "পিছনের দিকে"। সুতরাং, আমি PyFunctionalপ্যাকেজটি ব্যবহার করার পরামর্শ দিচ্ছি ( https://pypi.org/project/PyFunctional/ )। এখানে দুটিয়ের তুলনা করা হল:

flight_destinations_dict = {'NY': {'London', 'Rome'}, 'Berlin': {'NY'}}

PyFunctional সংস্করণ

খুব সুসংগঠিত বাক্য গঠন। তুমি বলতে পারো:

"আমার কাছে বিমানের গন্তব্যগুলির ক্রম রয়েছে which যার মধ্যে থেকে আমি শহরটি ডিকের মানগুলিতে থাকলে ডিক কীটি পেতে চাই Finally অবশেষে, প্রক্রিয়াটিতে আমি যে খালি তালিকাগুলি তৈরি করেছি তা ফিল্টার করে ফেলব।"

from functional import seq  # PyFunctional package to allow easier syntax

def find_return_flights_PYFUNCTIONAL_SYNTAX(city, flight_destinations_dict):
    return seq(flight_destinations_dict.items()) \
        .map(lambda x: x[0] if city in x[1] else []) \
        .filter(lambda x: x != []) \

ডিফল্ট পাইথন সংস্করণ

সবই পিছনের দিকে। আপনার বলতে হবে:

"ঠিক আছে, সুতরাং, একটি তালিকা আছে I আমি এটির বাইরে খালি তালিকাগুলি ফিল্টার করতে চাই Why কেন? কারণ শহরটি ডিক্ট মানের মধ্যে থাকলে আমি প্রথমে ডিক কীটি পেয়েছিলাম Oh ওহ, আমি যে তালিকাটি এটি করতে যাচ্ছি তা হ'ল উড়ান_দর্শনগুলি_ডিক্ট। "

def find_return_flights_DEFAULT_SYNTAX(city, flight_destinations_dict):
    return list(
        filter(lambda x: x != [],
               map(lambda x: x[0] if city in x[1] else [], flight_destinations_dict.items())
               )
    )
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.